import unittest

import numpy as np
import pandas as pd
from backend.db import DB
import tempfile
import os

from backend.his_io import dtypes


class TestDb(unittest.TestCase):
    def setUp(self):
        self.temp_dir = tempfile.TemporaryDirectory()
        self.temp_file = os.path.join(self.temp_dir.name, 'test_db.json')
        self.db = DB(self.temp_file)


    def test_db(self):
        session = None

        with self.subTest('create_session'):
            session = self.db.create_session()
            self.assertIsNotNone(session)
            self.assertGreater(len(session.token), 16)
            self.assertTrue(session.token in self.db.list_tokens())

        with self.subTest('store_session'):
            session.table_name = 'Test Table'
            session.students_df = pd.DataFrame(columns=['Examplan.id', 'Matrikelnummer', 'PrüfungsNr.', 'Titel', 'Nachname', 'Vorname', 'Leistung', 'Versuch',
                                                        'Status', 'ECTS', 'Semester', 'Jahr', 'Prüfungsperiode', 'Vermerk', 'Thema', 'Beginn',
                                                        'Gepl. Ende', 'Tatsächl. Ende', 'Prüfungsart', 'Prüfungsform', 'LockVersion'])
            session.students_df = session.students_df.astype(dtypes.students_table)
            
            session.students_df = pd.concat([session.students_df, pd.DataFrame({
                'Examplan.id': 1, 'PrüfungsNr.': 'P001', 'Titel': 'Math', 'Matrikelnummer': 123456, 'Nachname': 'Doe', 'Vorname': 'John', 'Leistung': 'A', 'Versuch': 1,
                'Status': 'Passed', 'ECTS': 5, 'Semester': 'WS2021', 'Jahr': 2021, 'Prüfungsperiode': 'Winter', 'Vermerk': '', 'Thema': '', 'Beginn': '', 'Gepl. Ende': '',
                'Tatsächl. Ende': '', 'Prüfungsart': '', 'Prüfungsform': '', 'LockVersion': '1e851fa6-6f69-4fe4-a1a8-510ab8e5c6ea=0,eeecd36a-ee4a-4897-b7db-464542618fb3=0,3fda53aa-2106-4f8b-a832-03aa57917cb2=0,'
            }, index=[0])])

            session.students_df = pd.concat([session.students_df, pd.DataFrame({
                'Examplan.id': 2, 'PrüfungsNr.': 'P002', 'Titel': 'Physics', 'Matrikelnummer': 654321, 'Nachname': 'Smith', 'Vorname': 'Jane', 'Leistung': 'B', 'Versuch': 1,
                'Status': 'Passed', 'ECTS': 5, 'Semester': 'WS2021', 'Jahr': 2021, 'Prüfungsperiode': 'Winter', 'Vermerk': '', 'Thema': '', 'Beginn': '', 'Gepl. Ende': '',
                'Tatsächl. Ende': '', 'Prüfungsart': '', 'Prüfungsform': '', 'LockVersion': 'fd952c3a-c789-4af2-88fd-0dbe8ea0e68b=0,5a639ec2-eec4-4d53-bd92-5ed368f164c3=0,26270d08-a83b-4c2a-94e3-fc732553ef99=0,'
            }, index=[1])])

            session.students_df = pd.concat([session.students_df, pd.DataFrame({
                'Examplan.id': 3, 'PrüfungsNr.': 'P003', 'Titel': 'Chemistry', 'Matrikelnummer': 789012, 'Nachname': 'Brown', 'Vorname': 'Alice', 'Leistung': 'C', 'Versuch': 1,
                'Status': 'Passed', 'ECTS': 5, 'Semester': 'WS2021', 'Jahr': 2021, 'Prüfungsperiode': 'Winter', 'Vermerk': '', 'Thema': '', 'Beginn': '', 'Gepl. Ende': '',
                'Tatsächl. Ende': '', 'Prüfungsart': '', 'Prüfungsform': '', 'LockVersion': 'ee3f3068-dad7-489c-a5e7-f2eccaedacf7=0,92e970b1-d447-4009-8dde-676d6a31a337=0,8c29a40c-8aa1-4585-b77b-78b410e3d12d=0,'
            }, index=[2])])
            session.students_df.set_index('Matrikelnummer', inplace=True)

            session.points_df = session.students_df.copy()
            session.points_df['Punkte'] = [1, 2, 3]
            session.points_df['Note'] = ['1,0', '2,0', '3,0']
            session.points_df['1'] = [1, 2, 3]
            session.points_df['2'] = [1, 2, 3]
            session.his_header = pd.DataFrame(columns=['5160 - Rocket Science (Prüfung) | Prüfer/-in: Schröder, Enrico | Wintersemester 2023/24 | Prüfungsperiode 1', None, 'EXAM_CHECK_TOKEN', 'startHISsheet'])
            session.his_header = session.his_header.astype(dtypes.his_header)
            session.max_points = 123
            session.grade_1_0 = 0.50
            session.grade_4_0 = 0.20

            self.db.save_session(session)
            self.assertTrue(session.token in self.db.list_tokens())

        with self.subTest('get_session'):
            session2 = self.db.get_session(session.token)
            self.assertIsNotNone(session2)
            self.assertEqual(session, session2)
        

        return session