"""
Converting the Profiler output to that that is expected by the contract definition
TODO: Crate an abstraction which takes care of this mapping. Or consider doing it in the profiler.
"""
from typing import List, Dict


def generate_metadata(info: Dict):
    if "database" in info:
        return {
            "identifier": f"{info['database']}.{info['schema']}.{info['table']}"
        }
    elif "BUCKET" in info:
        return {
            "identifier": f"{info['BUCKET']}/{info['FILE_PATH']}?file_format={info['FILE_FORMAT']}",
            "bucket": info['BUCKET']
        }
    else:
        raise Exception("Invalid metadata")


def schema_mapper(schemas) -> List[Dict]:
    """
    Function which maps the schema generated by the profiler to the format
    expected by the contract definition
    :param columns_info: The schema generated by the profiler
    return: The schema in the format expected by the contract definition
    example:
    columns_info = [
        {
            "COL_NAME": "user_id",
            "COL_TYPE": "number",
            "COL_SORT_ORDER": "1",
            "DESCRIPTION": null,
            "IS_VIEW": "false",
            "table": "user",
            "schema": "dbt",
            "database": "analytics",
            "description": null,
            "id": "a3a617d01fba40b3abea57af0ee009a3"
        },...
    ]
    output: [
        {
            "metadata": {
                "database": "analytics",
                "schema": "dbt",
                "table": "user",
            },
            "table_schema": {
                 "column_name": "column_type"
            }
    ]
    # TODO: Create a class with the schemas defined.
    """
    resources = {}

    # Iterate over the column information
    for schema in schemas:
        for row in schema:
            resource = generate_metadata(row)
            identifier = resource["identifier"]
            column = {row["COL_NAME"]: row["COL_TYPE"]}
            if identifier in resources:
                resources[identifier]["resource_schema"].update(column)
            else:
                resources[identifier] = {"metadata": resource, "resource_schema": column}

    return list(resources.values())

