# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/classes/CodeEngineManifest.ipynb.

# %% auto 0
__all__ = ['CodeEngineManifest']

# %% ../../nbs/classes/CodeEngineManifest.ipynb 1
from .CodeEngineManifest_Function import CodeEngineManifest_Function, CodeEngineManifest_Argument, CodeEngine_Argument, PythonTypeToSchemaType

# %% ../../nbs/classes/CodeEngineManifest.ipynb 2
import domolibrary.utils.convert as dmcv
import domolibrary.utils.files as dmfi

from typing import Dict, Any, List
from dataclasses import dataclass

# %% ../../nbs/classes/CodeEngineManifest.ipynb 6
@dataclass
class CodeEngineManifest:
    functions: list[CodeEngineManifest_Function]
    configuration: Dict[str, Any]

    raw: str = None

    @classmethod
    def from_python_file(
        cls, file_path: str, accounts_mapping: List[Any]
    ) -> "CodeEngineManifest":
        """
        Analyze all functions in a Python script file and return a structured manifest.

        This is the main public method that orchestrates the complete analysis process.
        It loads the specified file, parses its AST, and generates comprehensive metadata
        descriptions for every function found in the script, returning them as a Manifest object.

        Args:
            file_path (str): Path to the Python script file to analyze

        Returns:
            Manifest: A manifest object containing:
                - functions (List[FunctionMetadata]): List of function metadata objects
                - configuration (Dict[str, Any]): Configuration dictionary with accountsMapping

        Error Handling:
            - Returns a Manifest with empty functions list if file loading fails
            - Prints error messages for individual function analysis failures but continues processing
            - Skips functions that cannot be analyzed due to errors

        Example:
            >>> analyzer = CodeEngineScriptAnalyzer()
            >>> manifest = analyzer.analyze_all_functions('my_script.py')
            >>> for func in manifest.functions:
            ...     print(f"Function: {func.name} ({len(func.inputs)} parameters)")

        Note:
            This method walks the entire AST and processes all function definitions found,
            including nested functions and methods within classes.
        """
        content = dmcv.convert_python_to_ast_module(
            python_file_path=file_path, return_str=True
        )

        ast_module = dmcv.convert_python_to_ast(python_str=content, return_str=False)

        return cls(
            functions=[
                CodeEngineManifest_Function.from_ast_function(ast_fn, content=content)
                for ast_fn in dmcv.extract_ast_functions(ast_module)
            ],
            configuration={"accountsMapping": accounts_mapping or []},
        )

    @classmethod
    def from_python_string(
        cls, python_str: str, accounts_mapping: List[Any]
    ) -> "CodeEngineManifest":
        """
        Analyze all functions in a Python script string and return a structured manifest.

        This is the main public method that orchestrates the complete analysis process.
        It loads the specified string, parses its AST, and generates comprehensive metadata
        descriptions for every function found in the script, returning them as a Manifest object.

        Args:
            python_str (str): Python script content to analyze

        Returns:
            Manifest: A manifest object containing:
                - functions (List[FunctionMetadata]): List of function metadata objects
                - configuration (Dict[str, Any]): Configuration dictionary with accountsMapping

        Error Handling:
            - Returns a Manifest with empty functions list if string loading fails
            - Prints error messages for individual function analysis failures but continues processing
            - Skips functions that cannot be analyzed due to errors

        Example:
            >>> analyzer = CodeEngineScriptAnalyzer()
            >>> manifest = analyzer.analyze_all_functions('def my_func(x): return x')
            >>> for func in manifest.functions:
            ...     print(f"Function: {func.name} ({len(func.inputs)} parameters)")

        Note:
            This method walks the entire AST and processes all function definitions found,
            including nested functions and methods within classes.
        """
        ast_module = dmcv.convert_python_to_ast_module(
            python_str=python_str, return_str=False
        )

        return cls(
            functions=[
                CodeEngineManifest_Function.from_ast_function_def(
                    ast_fn, original_module_string=python_str
                )
                for ast_fn in dmcv.extract_ast_functions(ast_module)
            ],
            configuration={"accountsMapping": accounts_mapping or []},
        )

    @classmethod
    def from_api(cls, obj):
        cem = cls.from_python_string(python_str=obj["code"], accounts_mapping=[])
        cem.raw = obj

        for cfn in cem.functions:
            cfn._target_from_api = next(
                (
                    fn_obj
                    for fn_obj in obj["functions"]
                    if fn_obj and fn_obj["name"] == cfn.name
                ),
                None,
            )

        return cem

    def download_source_code(self, export_folder: str = "./EXPORT", replace_folder : bool = False):

        dmfi.upsert_file(os.path.join(export_folder, 'index.py'), content=self.raw['code'],
                         replace_folder=replace_folder)

        return [
            fn.download_source_code(export_folder=export_folder)
            for fn in self.functions
        ]
        # return file_name
