"""
@package tests.test_dispatch
unit tests for pmsco.dispatch

the purpose of these tests is to mainly to check the syntax, and correct data types,
i.e. anything that could cause a run-time error.

to run the tests, change to the directory which contains the tests directory, and execute =nosetests=.

@author Matthias Muntwiler, matthias.muntwiler@psi.ch

@copyright (c) 2018 by Paul Scherrer Institut @n
Licensed under the Apache License, Version 2.0 (the "License"); @n
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import six

import copy
import unittest
import pmsco.dispatch as dispatch


class TestCalcID(unittest.TestCase):
    def setUp(self):
        # before each test method
        pass

    def tearDown(self):
        # after each test method
        pass

    def test_levels(self):
        cid = dispatch.CalcID(1, 2, 3, -1, -1)
        result = cid.levels
        expected = dispatch.CALC_LEVELS
        self.assertIsInstance(cid, tuple)
        self.assertEqual(result, expected)

    def test_level(self):
        cid = dispatch.CalcID(1, 2, 3, -1, -1)
        result = cid.level
        expected = dispatch.CALC_LEVELS[2]
        self.assertEqual(result, expected)
        cid = dispatch.CalcID(-1, -1, -1, -1, -1)
        result = cid.level
        expected = ''
        self.assertEqual(result, expected)

    def test_numeric_level(self):
        cid = dispatch.CalcID(1, 2, 3, -1, -1)
        result = cid.numeric_level
        expected = 2
        self.assertEqual(result, expected)
        cid = dispatch.CalcID(-1, -1, -1, -1, -1)
        result = cid.numeric_level
        expected = -1
        self.assertEqual(result, expected)

    def test_collapse_levels(self):
        cid = dispatch.CalcID(1, 2, 3, 4, 5)
        result = cid.collapse_levels(dispatch.CALC_LEVELS[2])
        expected = dispatch.CalcID(1, 2, 3, -1, -1)
        self.assertEqual(result, expected)
        result = cid.collapse_levels(-1)
        expected = dispatch.CalcID(-1, -1, -1, -1, -1)
        self.assertEqual(result, expected)


class TestCalculationTask(unittest.TestCase):
    def setUp(self):
        self.sample = dispatch.CalculationTask()
        self.sample.id = dispatch.CalcID(11, 12, 13, 14, 15)
        self.sample.parent_id = dispatch.CalcID(21, 22, 23, 24, 25)
        self.sample.model = {'A': 31, 'B': 32}
        self.sample.file_root = "testfile"
        self.sample.file_ext = ".ext"
        self.sample.result_filename = "resultfile"
        self.sample.modf_filename = "modffile"
        self.sample.result_valid = True
        # self.sample.time = datetime.timedelta()
        # self.sample.files = {}
        # self.sample.region = {}
        self.sample.rfac = 0.123456

    def tearDown(self):
        pass

    def test_change_id(self):
        result = copy.deepcopy(self.sample)
        self.sample.id = dispatch.CalcID(11, 92, 13, 14, 15)
        result.change_id(scan=92)
        self.assertEqual(result, self.sample)

    def test_get_mpi_message(self):
        result = self.sample.get_mpi_message()
        expected = {'model': 11, 'scan': 12, 'domain': 13, 'emit': 14, 'region': 15}
        self.assertEqual(result['id'], expected)
        self.assertEqual(result['model'], self.sample.model)
        self.assertEqual(result['result_filename'], self.sample.result_filename)
        self.assertEqual(result['result_valid'], self.sample.result_valid)

    def test_set_mpi_message(self):
        result = dispatch.CalculationTask()
        msg = self.sample.get_mpi_message()
        result.set_mpi_message(msg)
        self.assertEqual(result, self.sample)

    def test_format_filename(self):
        result = self.sample.format_filename(emit=94)
        expected = "testfile_11_12_13_94_15.ext"
        self.assertEqual(result, expected)
