"""
Tests for the diagonstics.py file
"""
import pytest
import numpy as np
from turbopy.core import Simulation
from turbopy.diagnostics import FieldDiagnostic


@pytest.fixture(name='simple_field')
def field_fixt():
    """Pytest fixture for FieldDiagnostic class"""
    sim_dic = {"Grid": {"N": 2, "r_min": 0, "r_max": 1},
               "Clock": {"start_time": 0,
                         "end_time": 10,
                         "num_steps": 100},
               "Tools": {"ExampleTool": {}},
               "PhysicsModules": {"ExampleModule": {}}}
    field_dic = {"component": "Component",
                 "field": "Field",
                 "output_type": "csv",
                 "filename": "output.csv",
                 "dump_interval": 1}
    field = FieldDiagnostic(Simulation(sim_dic), field_dic)
    field.owner.read_clock_from_input()
    field.owner.read_grid_from_input()
    return field

#Test methods for FieldDiagnostic class
def test_init_should_create_class_instance_when_called(simple_field):
    """Tests init method in FieldDiagnostic class"""
    assert simple_field.component == "Component"
    assert simple_field.field_name == "Field"
    assert simple_field.output == "csv"
    assert simple_field.field is None
    assert simple_field.dump_interval is None
    assert simple_field.last_dump is None
    assert simple_field.diagnostic_size is None
    assert simple_field.field_was_found is False

def test_check_step_should_update_last_dump_after_dump_interval_has_passed(simple_field):
    """Tests check_step method in FieldDiagnostic class"""
    simple_field.inspect_resource({"Field": np.linspace(0, 1, 2)})
    simple_field.initialize()
    simple_field.owner.clock.time = 1
    simple_field.check_step()
    assert simple_field.last_dump == 1

def test_initialize_should_set_remaining_parameters_when_called(simple_field):
    """Tests initialize method in FieldDiagnostic class"""
    with pytest.raises(RuntimeError):
        assert simple_field.initialize()
    simple_field.inspect_resource({"Field": np.linspace(0, 1, 2)})
    simple_field.initialize()
    assert simple_field.dump_interval == 1
    assert simple_field.last_dump == 0
    assert simple_field.diagnostic_size == (11, 2)
    assert simple_field.output_function == simple_field.csv_diagnose
    assert simple_field.csv.filename == "output.csv"
    assert np.allclose(simple_field.csv.buffer, np.zeros((11, 2)))
    assert simple_field.csv.buffer_index == 0

def test_inspect_resource_should_assign_field_attribute_if_field_name_in_resource(simple_field):
    """Tests inspect_resource method in FieldDiagnostic class"""
    array_to_share = np.linspace(0, 1, 2)
    simple_field.inspect_resource({"Field": array_to_share})
    assert simple_field.field_was_found is True
    assert simple_field.field is array_to_share

def test_csv_diagnose_should_append_data_to_csv_when_called(simple_field):
    """Tests csv_diagnose method in FieldDiagnostic class"""
    simple_field.inspect_resource({"Field": np.linspace(0, 1, 2)})
    simple_field.initialize()
    simple_field.csv.append(simple_field.field)
    assert np.allclose(simple_field.csv.buffer[simple_field.csv.buffer_index-1, :],
                       simple_field.field)
    assert simple_field.csv.buffer_index == 1
