from numpy.testing._private.utils import assert_almost_equal
import pytest
import json
import numpy as np

from material.orthotropic import Orthotropic
from ply.ply import Ply
from laminate.laminate import Laminate
from panel.panel import Panel
from loads.loads import Loads
from lamfail.lamfail import Lamfail

materialFile = "materials.json"
plyFile = "plies.json"
laminateFile = "laminates.json"
panelFile = "panels.json"
loadsFile = "loads.json"

NT = np.array([-0.07881, -0.07881, 0.0])

class TestLamfailClass():
    """Unittest for Lamfail python object"""

    materials = {}
    plies = {}
    laminates = {}
    panels = {}
    loads = {}

    def setup_class(cls):
        """Set up Lamfail from the material, ply, laminate, loads, panel file."""

        with open(materialFile, 'r') as fh:
            jsonData = json.load(fh)
        for materialDict in jsonData["materials"]:
            matID = materialDict["matID"]
            E1 = materialDict["E1"]
            E2 = materialDict["E2"]
            G12 = materialDict["G12"]
            G13 = materialDict["G13"]
            G23 = materialDict["G23"]
            v12 = materialDict["v12"]
            alpha1 = materialDict["alpha1"]
            alpha2 = materialDict["alpha2"]
            beta1 = materialDict["beta1"]
            beta2 = materialDict["beta2"]
            cls.materials[matID] = Orthotropic(matID=matID, E1=E1, E2=E2, G12=G12, G13=G13, G23=G23, v12=v12,
            alpha1=alpha1, alpha2=alpha2, beta1=beta1, beta2=beta2)

        with open(plyFile, 'r') as fh:
            jsonData = json.load(fh)
        for plyDict in jsonData["plies"]:
            plyID = plyDict["plyID"]
            angle = plyDict["angle"]
            material = cls.materials[plyDict["material"]]
            thickness = plyDict["thickness"]
            cls.plies[plyID] = Ply(plyID=plyID, angle=angle, material=material, thickness=thickness)

        with open(laminateFile, 'r') as fh:
            jsonData = json.load(fh)
        for laminateDict in jsonData["laminates"]:
            lamID = laminateDict["lamID"]
            stacking_sequence = [cls.plies[str(plyID)] for plyID in laminateDict["stacking_sequence"]]
            offset = laminateDict["offset"]
            cls.laminates[lamID] = Laminate(lamID=lamID, stacking_sequence=stacking_sequence, offset=offset)
            #cls.laminates[id]._A44 = cls.laminates[id].A[1,1]
            #cls.laminates[id]._A55 = cls.laminates[id]._A44
            #cls.laminates[id]._A45 = 0.0
            #cls.laminates[id]._D = numpy.array([[3147.83, 1291.2, 0], [1291.2, 2795.36, 0], [0, 0, 1256.93]])
            #cls.laminates[id]._D = numpy.array([[45.094, 23.663, 0], [23.663, 35.523, 0], [0, 0, 26.047]])

        with open(panelFile, 'r') as fh:
            jsonData = json.load(fh)
        for panelDict in jsonData["panels"]:
            panelID = panelDict["panelID"]
            length = panelDict["length"]
            width = panelDict["width"]
            laminate = cls.laminates[panelDict["laminate"]]
            boundary_condition = panelDict["boundary_condition"]
            cls.panels[panelID] = Panel(panelID=panelID, length=length, width=width, laminate=laminate, boundary_condition=boundary_condition)
            cls.panels[panelID].number_of_terms = 2

        with open(loadsFile, 'r') as fh:
            jsonData = json.load(fh)
        for loadsDict in jsonData["loads"]:
            loadsID = loadsDict["loadsID"]
            panelID = loadsDict["panelID"]
            Nxx = loadsDict["Nxx"]
            Nyy = loadsDict["Nyy"]
            Nxy = loadsDict["Nxy"]
            Mxx = loadsDict["Mxx"]
            Myy = loadsDict["Myy"]
            Mxy = loadsDict["Mxy"]
            Qyz = loadsDict["Qyz"]
            Qxz = loadsDict["Qxz"]
            deltaT = loadsDict["deltaT"]
            deltaC = loadsDict["deltaC"]
            cls.loads[loadsID] = Loads(loadsID=loadsID, panelID=panelID, Nxx=Nxx, Nyy=Nyy, Nxy=Nxy, Mxx=Mxx, Myy=Myy, Mxy=Mxy,
            Qyz=Qyz, Qxz=Qxz, deltaT=deltaT, deltaC=deltaC)

        cls.lmf = Lamfail(panel = cls.panels["1"], loads = cls.loads["1"])

    def test_init_lamfail(self):
        """Unitest to check if Solver004 properly initialized."""

        assert self.lmf.panel.panelID == "1"
        assert self.lmf.loads.loadsID == "1"

    def test_NT(self):
        """Unittest to check NT."""

        #print(self.s004.NT)
        np.testing.assert_array_almost_equal(self.lmf.NT, NT, decimal=3)