from typing import BinaryIO, Any
from io import BytesIO
import os, logging

from markitdown import (
    MarkItDown,
    DocumentConverter,
    DocumentConverterResult,
    StreamInfo,
    PRIORITY_SPECIFIC_FILE_FORMAT
)
import aspose.words as aw
from aspose_words_markitdown.aspose_words_converter import AsposeWordsConverter


__plugin_interface_version__ = (
    1  # The version of the plugin interface that this plugin uses.
)

# Set the priority to be just below PRIORITY_SPECIFIC_FILE_FORMAT.
ASPOSE_WORDS_PRIORITY_FORMAT = PRIORITY_SPECIFIC_FILE_FORMAT - 1

MARKDOWN_ENCODING = "utf-8"


def register_converters(markitdown: MarkItDown, **kwargs):
    # Called during construction of MarkItDown instances to register converters provided by plugins.
    # Simply create and attach an AsposeDocumentConverter instance.
    markitdown.register_converter(AsposeDocumentConverter(), priority=ASPOSE_WORDS_PRIORITY_FORMAT)


""" To activate your Aspose License, set the corresponding environment variable.
    Refer to the OS-specific instructions below:
    Unix-based (Linux/macOS):
        export ASPOSE_WORDS_LICENSE_PATH="/path/to/license/aspose.words.lic"
    Windows-based:
        set ASPOSE_WORDS_LICENSE_PATH=c:\\path\\to\\license\\aspose.words.lic """
class LicenseManager:
    def apply_license(self, license_path: str = None):
        if license_path is None:
            license_path = os.getenv("ASPOSE_WORDS_LICENSE_PATH")
        if license_path is not None and os.path.exists(license_path):
            logging.info(f"Applying Aspose.Words license from: {license_path}")
            license = aw.License()
            license.set_license(license_path)
        else:
            logging.warning("No valid Aspose.Words license found. Running in Evaluation mode. Please set the ASPOSE_WORDS_LICENSE_PATH environment variable.")


class AsposeDocumentConverter(DocumentConverter):

    def accepts(
        self,
        file_stream: BinaryIO,
        stream_info: StreamInfo,
        **kwargs: Any,
    ) -> bool:
        file_format = AsposeWordsConverter.get_aspose_format(stream_info.extension, 
                                                             stream_info.mimetype)
        return file_format != aw.LoadFormat.UNKNOWN


    def convert(
        self,
        file_stream: BinaryIO,
        stream_info: StreamInfo,
        **kwargs: Any,
    ) -> DocumentConverterResult:
        LicenseManager().apply_license()
        
        md_converter = AsposeWordsConverter()
        file_format = AsposeWordsConverter.get_aspose_format(stream_info.extension, 
                                                             stream_info.mimetype)
        md_data, title = md_converter.convert(BytesIO(file_stream.read()), 
                                              file_format,
                                              stream_info.filename)
        return DocumentConverterResult(title=title,
                                       markdown=md_data.getvalue().decode(MARKDOWN_ENCODING))