# Copyright (c) 2026 Luigi Paone <ppc.luigi.paone@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause

"""Tests for Typst cheat sheets generation.

These tests verify the Typst and PDF cheat sheet generation for:
- Concrete material properties (NTC2018)
- Rebar material properties (NTC2018)
- Beam minimum area (NTC2018)
- Plate minimum area (EC2-1-1)
"""

from pathlib import Path

from pycivil.EXAStructural.cheatsheets.codeEC2Rules import (
    PlateMinimumArea,
    PlateMinimumAreaInput,
    PlateMinimumAreaLogs,
    SolverPlateMinRebar,
)
from pycivil.EXAStructural.cheatsheets.codeNTC2018Rules import (
    BeamMinimumArea,
    BeamMinimumAreaInput,
    BeamMinimumAreaLogs,
    BeamMinimumAreaOutput,
    ConcreteMaterial,
    ConcreteMaterialInput,
    ConcreteMaterialOutput,
    RebarMaterial,
    RebarMaterialInput,
    RebarMaterialOutput,
    SolverBeamMinRebar,
    SolverConcrete,
    SolverSteelRebar,
)
from pycivil.EXAUtils import typstCheatSheets
from pycivil.EXAUtils.report import (
    TypstFragment,
    TypstReporter,
    ReportTemplateEnum,
    getTypstTemplatesPath,
)


def test_concrete_material_typst(tmp_path: Path):
    """Test concrete material cheat sheet generation in Typst format."""
    matInput = ConcreteMaterialInput()
    solver = SolverConcrete(inputModel=matInput)

    assert solver.run()

    outputData = solver.getModelOutput()
    assert isinstance(outputData, ConcreteMaterialOutput)
    material = ConcreteMaterial(inputData=matInput, outputData=outputData)

    typstTemplatePath = getTypstTemplatesPath()

    fragBuilder = typstCheatSheets.ConcreteMaterialTypstCS(
        typstTemplatePath=typstTemplatePath, data=material
    )

    frag_title = TypstFragment(typstTemplatePath)
    frag_title.add(line="== Calcestruzzo adottato per l'elemento")
    frag = fragBuilder.buildFragment()

    reporter = TypstReporter(typstTemplatePath)
    reporter.linkFragments(
        template=ReportTemplateEnum.TYP_ENG_CAL, fragments=[frag_title, frag]
    )
    reporter.compileDocument(path=str(tmp_path), fileName="TYP_CS_CONCRETE", output_format="pdf")
    assert tmp_path.joinpath("TYP_CS_CONCRETE.typ").exists()
    assert tmp_path.joinpath("TYP_CS_CONCRETE.pdf").exists()
    assert tmp_path.joinpath("TYP_CS_CONCRETE.pdf").stat().st_size > 0


def test_rebar_material_typst(tmp_path: Path):
    """Test rebar material cheat sheet generation in Typst format."""
    matInput = RebarMaterialInput()
    solver = SolverSteelRebar(inputModel=matInput)

    assert solver.run()
    outputData = solver.getModelOutput()
    assert isinstance(outputData, RebarMaterialOutput)
    material = RebarMaterial(inputData=matInput, outputData=outputData)

    typstTemplatePath = getTypstTemplatesPath()
    fragBuilder = typstCheatSheets.RebarMaterialTypstCS(
        typstTemplatePath=typstTemplatePath, data=material
    )
    frag_title = TypstFragment(typstTemplatePath)
    frag_title.add(line="== Acciaio adottato per l'elemento")
    frag = fragBuilder.buildFragment()

    reporter = TypstReporter(typstTemplatePath)
    reporter.linkFragments(
        template=ReportTemplateEnum.TYP_ENG_CAL, fragments=[frag_title, frag]
    )
    reporter.compileDocument(path=str(tmp_path), fileName="TYP_CS_REBAR", output_format="pdf")
    assert tmp_path.joinpath("TYP_CS_REBAR.typ").exists()
    assert tmp_path.joinpath("TYP_CS_REBAR.pdf").exists()
    assert tmp_path.joinpath("TYP_CS_REBAR.pdf").stat().st_size > 0


def test_beam_minimum_area_typst(tmp_path: Path):
    """Test beam minimum area cheat sheet generation in Typst format."""
    dataInput = BeamMinimumAreaInput()
    solver = SolverBeamMinRebar(inputModel=dataInput)

    assert solver.run()

    logsData = solver.getModelLogs()
    assert isinstance(logsData, BeamMinimumAreaLogs)

    outputData = solver.getModelOutput()
    assert isinstance(outputData, BeamMinimumAreaOutput)

    data = BeamMinimumArea(
        inputData=dataInput,
        logsData=logsData,
        outputData=outputData,
    )

    typstTemplatePath = getTypstTemplatesPath()

    fragBuilder = typstCheatSheets.BeamMinimumAreaTypstCS(
        typstTemplatePath=typstTemplatePath, data=data
    )

    frag_title = TypstFragment(typstTemplatePath)
    frag_title.add(line="== Area minima delle travi secondo NTC2018")
    frag = fragBuilder.buildFragment()

    reporter = TypstReporter(typstTemplatePath)
    reporter.linkFragments(
        template=ReportTemplateEnum.TYP_ENG_CAL, fragments=[frag_title, frag]
    )
    reporter.compileDocument(path=str(tmp_path), fileName="TYP_CS_BEAM", output_format="pdf")
    assert tmp_path.joinpath("TYP_CS_BEAM.typ").exists()
    assert tmp_path.joinpath("TYP_CS_BEAM.pdf").exists()
    assert tmp_path.joinpath("TYP_CS_BEAM.pdf").stat().st_size > 0


def test_plate_minimum_area_typst(tmp_path: Path):
    """Test plate minimum area cheat sheet generation in Typst format."""
    dataInput = PlateMinimumAreaInput()
    solver = SolverPlateMinRebar(inputModel=dataInput)

    assert solver.run()

    logsData = solver.getModelLogs()
    assert isinstance(logsData, PlateMinimumAreaLogs)

    data = PlateMinimumArea(
        inputData=dataInput,
        logsData=logsData,
    )

    typstTemplatePath = getTypstTemplatesPath()

    fragBuilder = typstCheatSheets.PlateMinimumAreaTypstCS(
        typstTemplatePath=typstTemplatePath, data=data
    )

    frag_title = TypstFragment(typstTemplatePath)
    frag_title.add(line="== Area minima delle piastre secondo EC2")
    frag = fragBuilder.buildFragment()

    reporter = TypstReporter(typstTemplatePath)
    reporter.linkFragments(
        template=ReportTemplateEnum.TYP_ENG_CAL, fragments=[frag_title, frag]
    )
    reporter.compileDocument(path=str(tmp_path), fileName="TYP_CS_PLATE", output_format="pdf")
    assert tmp_path.joinpath("TYP_CS_PLATE.typ").exists()
    assert tmp_path.joinpath("TYP_CS_PLATE.pdf").exists()
    assert tmp_path.joinpath("TYP_CS_PLATE.pdf").stat().st_size > 0
