#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script for testing the polynomialdatareader script.

@author: mark
"""

import logging
import unittest
import numpy as np
import solventmapcreator.io.polynomialdatareader as polynomialdatareader

logging.basicConfig()
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.WARN)

class PolynomialDataReaderTestCase(unittest.TestCase):
    """Test Case for the polynomialdatareader script.
    """
    def setUp(self):
        """Set up for tests.
        """
        self.expected_list = [['Order','Fit Range', 'RMSE', 'Covariance', 'Coefficients'],
                              ['1', 'All', '0.0154303350', '7.142857142857E-04',
                               '-5.000000000000E-02', '1.071428571429E+00']]
        self.expected_data_by_solvent_id = {"expected,poly,fit":{1:{"coefficients":np.array([-0.05, 
                                                                                             1.071428571429]),
                                                                    "RMSE":0.015430334996209221,
                                                                    "order":1,
                                                                    "covar":0.0007143}}}
    def tearDown(self):
        """Tear down after tests.
        """
        del self.expected_data_by_solvent_id
        del self.expected_list
    def test_parse_polynomial_data_file_list(self):
        """Test to see if expected information is read in from file list.
        """
        actual_data_by_solvent_id = polynomialdatareader.parse_polynomial_data_file_list(["resources/expected_poly_fit.csv"])
        self.assertListEqual(sorted(self.expected_data_by_solvent_id.keys()), sorted(actual_data_by_solvent_id.keys()))
        expected_poly_dictionary = self.expected_data_by_solvent_id["expected,poly,fit"]
        actual_poly_dictionary = actual_data_by_solvent_id["expected,poly,fit"]
        self.assertListEqual(sorted(expected_poly_dictionary.keys()), sorted(actual_poly_dictionary.keys()))
        for poly_order in expected_poly_dictionary.keys():
            expected_dictionary = expected_poly_dictionary[poly_order]
            actual_dictionary = actual_poly_dictionary[poly_order]
            for key in expected_dictionary.keys():
                if key == "RMSE" or key == "covar":
                    self.assertAlmostEqual(expected_dictionary[key], actual_dictionary[key])
                elif key == "order":
                    self.assertEqual(expected_dictionary[key], actual_dictionary[key])
                else:
                    np.testing.assert_array_almost_equal(expected_dictionary[key], actual_dictionary[key])
    def test_generate_solvent_id(self):
        """Test to see if expected id is extracted.
        """
        expected_id = "water"
        actual_id1 = polynomialdatareader.generate_solvent_id("water.csv", ".csv")
        self.assertEqual(expected_id, actual_id1)
        actual_id2 = polynomialdatareader.generate_solvent_id("resources/water.csv", ".csv")
        self.assertEqual(expected_id, actual_id2)
    def test_parse_polynomial_data_file(self):
        """Test to see if file is parsed as expected.
        """
        expected_poly_dictionary = self.expected_data_by_solvent_id["expected,poly,fit"]
        actual_poly_dictionary = polynomialdatareader.parse_polynomial_data_file("resources/expected_poly_fit.csv")
        self.assertListEqual(sorted(expected_poly_dictionary.keys()), sorted(actual_poly_dictionary.keys()))
        for poly_order in expected_poly_dictionary.keys():
            expected_dictionary = expected_poly_dictionary[poly_order]
            actual_dictionary = actual_poly_dictionary[poly_order]
            for key in expected_dictionary.keys():
                if key == "RMSE" or key == "covar":
                    self.assertAlmostEqual(expected_dictionary[key], actual_dictionary[key])
                elif key == "order":
                    self.assertEqual(expected_dictionary[key], actual_dictionary[key])
                else:
                    np.testing.assert_array_almost_equal(expected_dictionary[key], actual_dictionary[key])
        expected_poly_dict2 = {1:{"positive":self.expected_data_by_solvent_id["expected,poly,fit"][1],
                                 "negative":self.expected_data_by_solvent_id["expected,poly,fit"][1]}}
        actual_poly_dict2 = polynomialdatareader.parse_polynomial_data_file("resources/expected_poly_fit2.csv")
        for poly_order in expected_poly_dict2.keys():
            expected_mix_dictionary = expected_poly_dict2[poly_order]
            actual_mix_dictionary = actual_poly_dict2[poly_order]
            self.assertListEqual(sorted(expected_mix_dictionary.keys()),
                                 sorted(actual_mix_dictionary.keys()))
            for key in expected_mix_dictionary.keys():
                actual_dictionary = actual_mix_dictionary[key]
                expected_dictionary = expected_mix_dictionary[key]
                self.assertListEqual(sorted(expected_dictionary.keys()),
                                 sorted(actual_dictionary.keys()))
                for key in expected_dictionary.keys():
                    if key == "RMSE":
                        self.assertAlmostEqual(expected_dictionary[key],
                                               actual_dictionary[key])
                    elif key == "order":
                        self.assertEqual(expected_dictionary[key],
                                         actual_dictionary[key])
                    else:
                        np.testing.assert_array_almost_equal(expected_dictionary[key],
                                                             actual_dictionary[key])
    def test_read_polynomial_data_file(self):
        """Test to see if file is read as expected.
        """
        actual_list = polynomialdatareader.read_polynomial_data_file("resources/expected_poly_fit.csv")
        self.assertListEqual(self.expected_list, actual_list)
    def test_read_polynomial_data_line(self):
        """Test to see if line is read as expected.
        """
        expected_dictionary = self.expected_data_by_solvent_id["expected,poly,fit"][1]
        actual_dictionary = polynomialdatareader.read_polynomial_data_line(self.expected_list[1])
        self.assertListEqual(sorted(expected_dictionary.keys()), sorted(actual_dictionary.keys()))
        for key in expected_dictionary.keys():
            if key == "RMSE" or key == "covar":
                self.assertAlmostEqual(expected_dictionary[key], actual_dictionary[key])
            elif key == "order":
                self.assertEqual(expected_dictionary[key], actual_dictionary[key])
            else:
                np.testing.assert_array_almost_equal(expected_dictionary[key], actual_dictionary[key])