class TestMedEdNetToEDNATranslator(unittest.TestCase):

    def setUp(self):
        self.trans = MedEdNetToEDNATranslator(lambda: "", 'limesurvey_survey_471745.txt',
                'vvexport_471745.txt')

    def tearDown(self):
        self.trans = None

    def test_init(self):
        self.assertIsInstance(self.trans.survey_structure, SurveyStructure)
        self.assertEqual(len(self.trans.survey_structure.indexed_question_list),
                117, "survey_structure should be correctly populated")
        self.assertIsInstance(self.trans.responses, list)

    def test_massage_header(self):
        n_h, offset = self.trans.massage_header(self.trans.responses[:2])
        self.assertEqual(offset, 5, "offset should be 5, got {}".format(offset))
        self.assertEqual(len(n_h), 2, "should only be two headers")
        self.assertEqual(len(n_h[0]), 239,
                "header len should be 239, got {}".format(len(n_h[0])))
        self.assertEqual(len(n_h[0]), len(n_h[1]), "headers should be same len")
        self.assertEqual(n_h[1][offset:117+offset],
                [q.name for q in self.trans.survey_structure.indexed_question_list],
                "indexed question list should equal offset old header[1]")
        for i, q in enumerate(self.trans.survey_structure.indexed_question_list):
            self.assertEqual("responseStatus_" + q.name.replace("_", ""),
                    n_h[1][117 + offset + i],
                    "responseStatus_{0} != {1}".format(q.name.replace("_", ""),
                        n_h[1][117 + offset + i]))

    def test_code_responses(self):
        code_list = ["E111E", "E222E", "E444E", "E555E", "E777E", "E888E",
                "E999E"]
        bad_response_key = ["NA", "N/A", "NOT AVAILABLE", "NONE", "?"]

        iql = self.trans.survey_structure.indexed_question_list
        n_h, offset = self.trans.massage_header(self.trans.responses[:2])
        outp = self.trans.code_responses(self.trans.responses[2:], n_h, offset)
        self.assertEqual(len(outp), 24,
                "should be 24 responses, got {}".format(len(outp)))
        for resp in outp:
            self.assertEqual(len(resp), 239,
                    "response len should be 239, got {}, {}".format(len(resp), resp))
            for ans in resp[117+offset:]:
                self.assertIn(ans, code_list, "each question should be coded")
            for index, ans in enumerate(resp[offset:offset+117]):
                # if not ans:
                if iql[index].parent_question_scale == "M":
                    if not ans:
                        self.assertEqual(resp[index + offset + 117], "E222E",
                                "blanks in M-type questions should be 222")
                elif iql[index].parent_question_scale == "L":
                    if not ans and "other" in iql[index].name:
                        self.assertEqual(resp[index + offset + 117], "E222E",
                                "blank response for other SQ of L-type Q should be 222")
                    elif not ans:
                        self.assertEqual(resp[index + offset + 117], "E999E",
                                "missing answers should be marked 999")
                    else:
                        self.assertEqual(resp[index + offset + 117], "E111E",
                                "answered Qs should be marked 111")
                elif iql[index].parent_question_scale == ";":
                    if not ans:
                        self.assertEqual(resp[index + offset + 117], "E999E",
                                "missing ans for ;-type should be 999")
                    if ans.upper() in bad_response_key:
                        self.assertEqual(resp[index + offset + 117], "E111E",
                               """variations on 'n/a' should be coded as 111
                                for ;-type questions (LoT 1.1)""")
                elif iql[index].parent_question_logic:
                    if not ans:
                        self.assertEqual(resp[index + offset + 117], "E777E",
                                "unanswered Qs w skip logic should be 777")
                else:
                    if not ans:
                        self.assertEqual(resp[index + offset + 117], "E999E",
                                """
                                missing answers should be marked 999. offending
                                result: {}:{}>{}
                                """
                                .format(iql[index],ans,resp[index + offset + 117]))
                    else:
                        self.assertEqual(resp[index + offset + 117], "E111E",
                               """answered questions should be marked 111""")