import os

from nexusformat.nexus import nxopen

from assonant._nexus import NeXusObjectFactory
from assonant.data_classes import AssonantDataClass

from ._assonant_file_writer_interface import IAssonantFileWriter
from .exceptions import AssonantFileWriterError


class NexusFileWriter(IAssonantFileWriter):
    """NeXus File Writer.

    File Writer specialized on accessing data from AssonantDataClasses and
    write into a HDF5 file following NeXus data model standards.
    """

    def __init__(self):
        self.nexus_factory = NeXusObjectFactory()
        self.file_extension = ".nxs"

    def write_data(self, filepath: str, filename: str, data: AssonantDataClass):
        """Method for writing data into a NeXus file.

        File will be created if it doesn't exist yet, otherwise data will be add to NXroot object of the NeXus file.

        Args:
            filepath (str): Path where NeXus file will be saved.
            filename (str): Name that will be given to file.
            data (AssonantDataClass): AssonantDataClass that contains data
            to be saved in file.
        """
        nexus_filepath = os.path.join(filepath, os.path.splitext(filename)[0]) + self.file_extension
        print(nexus_filepath)
        try:
            with nxopen(nexus_filepath, mode="a").nxfile as nxf:
                nxobject = self.nexus_factory.create_nxobject(data, pack_into_nxroot=True)
                nxf.update(nxobject)
        except Exception as e:
            raise AssonantFileWriterError(
                f"NeXusFileWriter failed to write data into {filepath} due to the following exception: {repr(e)}"
            )
