# Copyright 2022 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import enum, shutil, pickle
from library import *
from matmul import *
from batch_matmul import *
from split_k_matmul import *
from pathlib import Path


###############################################################################
class EmitSourceMLIR:
    """Emitters for the operation MLIR source files."""

    def __init__(self, operation_path, dispatch_collection):
        self.operation_path = operation_path
        self.dispatch_collection = dispatch_collection
        self.operation = dispatch_collection.operation
        self.operation_kind = self.operation.operation_kind
        self.configuration_list = dispatch_collection.configuration_list
        self.operation_filepath = self.operation_path.joinpath(
            self.operation.name()
        ).with_suffix(".mlir")

        mlir_configuration_emitter = {
            OperationKind.Matmul: EmitMatmulCompilationInfo,
            OperationKind.SplitkMatmul: EmitMatmulCompilationInfo,
            OperationKind.BatchMatmul: EmitMatmulCompilationInfo,
        }
        self.configuration_emitter = mlir_configuration_emitter[self.operation_kind]()

        mlir_dispatch_emitter = {
            OperationKind.Matmul: EmitLinalgMatmulDispatch,
            OperationKind.SplitkMatmul: EmitLinalgMatmulDispatch,
            OperationKind.BatchMatmul: EmitLinalgBatchMatmulDispatch,
        }
        self.dispatch_emitter = mlir_dispatch_emitter[self.operation_kind]()

    def __enter__(self):
        self.operation_file = open(self.operation_filepath, "w")
        self.operation_file.write(f"// Finename: {self.operation_filepath}")

        # Emit all the configuration attribute tags.
        for configuration in self.configuration_list:
            self.operation_file.write(self.configuration_emitter.emit(configuration))
        return self

    def emit(self):
        """Emit the op func.func for each dispatch (operation + configuration)"""
        for dispatch in self.dispatch_collection.get_dispatches():
            print(
                f"    Emitting tuning configuration : {dispatch.configuration.name()}"
            )
            self.operation_file.write(self.dispatch_emitter.emit(dispatch))

    def __exit__(self, exc_type, exc_value, traceback):
        self.operation_file.close()


###############################################################################
class Manifest:
    """Manifest collects, filters, and stores dispatches in a data structure.
    Manifest organizes the dispatches in a dictionary.
    Usage:
     1. Create a manifest object with the command line arguments.
     2(a). Generate dispatches, append them in the manifest, and
           serialize them into a file.
     2(b). Load dispatches from a serialized file.

     ```python
     # generator.py usage:
     manifest = Manifest(args)
     manifest.initialize()

     # compile.py or profile.py usage:
     manifest = Manifest(args)
     manifest.load()
     ```
    """

    def __init__(self, args):
        self.args = args

        # Dictionary of operation kind to a list of dispatch collections. We
        # initialize the dictionary during the generation of dispatches and
        # serialize it to a file. The serialized file is used to load the
        # dispatches for compilation and profiling.
        # Datatype: OperationKind -> [DispatchCollection]
        self.dispatch_collection_map = {}

        # For operation kind-based filtering of dispatches.
        self.operation_kind_enabled = []

        # For name-based filtering of dispatches.
        self.dispatch_names = []
        self.ignore_dispatch_names = []

        if args.operation_kind == "all":
            self.operation_kind_enabled = []
        else:
            operations_kind_list = [
                OperationKind.Matmul,
                OperationKind.SplitkMatmul,
                OperationKind.BatchMatmul,
            ]
            self.operation_kind_enabled = [
                x
                for x in operations_kind_list
                if OperationKindNames[x] in args.operation_kind.split(",")
            ]

        if args.dispatches == "all":
            self.dispatch_names = []
        else:
            self.dispatch_names = [x for x in args.dispatches.split(",") if x != ""]

        # Paths to the generated directory (e.g. `./generated/linalg`).
        self.generated_path = Path(
            self.args.generated_dir, "generated", self.args.mlir_dialect
        )

        # Create the directories in self.generated_path, if it does not exist.
        if not self.generated_path.exists():
            self.generated_path.mkdir(parents=True, exist_ok=True)

        # Path to the serialized file.
        self.serialized_file_path = self.generated_path.joinpath("serialized_file.pkl")

    def _filter_string_matches(self, filter_string, haystack):
        """Returns true if all substrings appear in the haystack in order"""
        substrings = filter_string.split("*")
        for sub in substrings:
            idx = haystack.find(sub)
            if idx < 0:
                return False
            haystack = haystack[idx + len(sub) :]
        return True

    def is_enabled(self, dispatch):
        """Rerturns true if pass through filters based various criteria."""

        # Get the operation and configuration from the dispatch.
        operation = dispatch.operation
        configuration = dispatch.configuration

        # If the operation is not in the enabled list, return False.
        enabled = True

        # If operation_kind filter is enabled and the \
        # operation_kind in not in the enabled list, return False.
        if (
            len(self.operation_kind_enabled)
            and operation.operation_kind not in self.operation_kind_enabled
        ):
            enabled = False

        # If dispatch name-based filter regex is enabled match the \
        # dispatch name (operation+configuration) against all regexs \
        # in self.dispatch_names.
        if len(self.dispatch_names):
            name = dispatch.name()
            enabled = False

            # compare against each regex included in self.dispatch_names.
            for substr_to_match in self.dispatch_names:
                if self._filter_string_matches(substr_to_match, name):
                    enabled = True
                    break

        # Return the result of the filter.
        return enabled

    def append_dispatch_collection(self, dispatch_collection):
        """Appends one instance of DispatchCollection to the manifest."""
        operation_kind = dispatch_collection.operation.operation_kind
        if operation_kind not in self.dispatch_collection_map.keys():
            self.dispatch_collection_map[operation_kind] = []

        # Get all the dispatches from the dispatch_collection.
        dispatches = dispatch_collection.get_dispatches()

        # Filter dispatches based on the filter criteria.
        filtered_dispatch_collection = DispatchCollection(
            dispatch_collection.operation, []
        )
        for dispatch in dispatches:
            if self.is_enabled(dispatch):
                filtered_dispatch_collection.append(dispatch)

        # Only append the filtered_dispatch_collection if it has an unfiltered configuration.
        if len(filtered_dispatch_collection.configuration_list):
            self.dispatch_collection_map[operation_kind].append(
                filtered_dispatch_collection
            )

    def append(self, dispatch_collection_list):
        """Appends one instance of DispatchCollection to the manifest."""
        for dispatch_collection in dispatch_collection_list:
            self.append_dispatch_collection(dispatch_collection)

    def initialize(self):
        """Initialize the mainfest object by generating dispatches for supported operations."""
        self.append(CudaMatmulGenerator(self.args).generate())
        self.append(CudaSplitKMatmulGenerator(self.args).generate())
        self.append(CudaBatchMatmulGenerator(self.args).generate())

        # Serialize the initialized mainfest state.
        self.dump()

    def dump(self):
        """Serialize (dump) the self.dispatch_collection_map to a pickle file."""
        with open(self.serialized_file_path, "wb") as f:
            pickle.dump(self.dispatch_collection_map, f)

    def load(self):
        """Deserialize (load) the self.dispatch_collection_map from a pickle file."""
        if not self.serialized_file_path.exists():
            raise ValueError(f"Could not find : {self.serialized_file_path}")

        with open(self.serialized_file_path, "rb") as load_file:
            self.dispatch_collection_map = pickle.load(load_file)

    def emit(self):
        """Emits the operations in the Manifest to the build directory as MLIR source files.
        The operations are emitted in the dialect specified by the `mlir_dialect` flag.
        """

        # For each operation_kind create a directory and emit the operations with
        # all the configurations in the configuration_list into their seperate directories.
        for (
            operation_kind,
            dispatch_collection_list,
        ) in self.dispatch_collection_map.items():
            operation_kind_path = self.generated_path.joinpath(
                OperationKindNames[operation_kind]
            )

            # If the operation_kind_path does not exists, create it.
            if not operation_kind_path.exists():
                operation_kind_path.mkdir(parents=True, exist_ok=True)

            for dispatch_collection in dispatch_collection_list:
                operation_path = operation_kind_path.joinpath(
                    dispatch_collection.operation.name()
                )

                # If the operation_path does not exists, create it.
                if not operation_path.exists():
                    operation_path.mkdir()

                with EmitSourceMLIR(
                    operation_path, dispatch_collection
                ) as emit_mlir_source:
                    mlir_file_path = operation_path.joinpath(
                        dispatch_collection.operation.name()
                    ).with_suffix(".mlir")
                    print(f"[Generating]: {mlir_file_path}")

                    # Emit mlir source file for the dispatch_collection.operation with all the configurations
                    emit_mlir_source.emit()
