# Copyright (C) 2023 Thomas Hoppe (h0bB1T). All rights reserved.
#
# Unauthorized copying of this file via any medium is strictly prohibited.
# Proprietary and confidential.

# This adds properties to Collection, Object and Material, which are used to identify 
# the source of instances of those types, so if an element is imported into the scene
# it can be identified in the respective lists to not imported (implicitely) again.

import bpy, json

from typing import Union, List
from dataclasses import dataclass

from bpy.types import Collection, Object, Material

from .io import unified_path

@dataclass
class SourceInfo:
    file: str
    name: str


def store_source_info(element: Union[Collection, Object, Material], source_info: SourceInfo):
    """
    Add source info to property, encoded as json.
    """
    if hasattr(element, 'awp_source_info'):
        element.awp_source_info = json.dumps({
            'file': unified_path(source_info.file),
            'name': source_info.name
        })


def load_source_info(element: Union[Collection, Object, Material]) -> Union[SourceInfo, None]:
    """
    Load source info from object. in case of failure, return None.
    """
    if hasattr(element, 'awp_source_info'):
        try:
            js = json.loads(element.awp_source_info)
            return SourceInfo(js['file'], js['name'])
        except:
            # Not an error, just not set or invalid.
            pass
    return None


def get_element_with_source(
        elements: Union[List[Collection], List[Object], List[Material]],
        source_info: SourceInfo
    ) -> Union[Collection, Object, Material, None]:
    """
    Search list for element with the same source info, return it or None. elements is bpy.data.objects, ..
    """
    fixed_file = unified_path(source_info.file)
    for e in elements:
        info = load_source_info(e)
        if info and info.file == fixed_file and info.name == source_info.name:
            return e
    return None


def init_type_properties():
    """
    Register on startup.
    """
    Collection.awp_source_info = bpy.props.StringProperty(name='AWP Info', description='Asset Wizard pro source information')
    Object.awp_source_info = bpy.props.StringProperty(name='AWP Info', description='Asset Wizard pro source information')
    Material.awp_source_info = bpy.props.StringProperty(name='AWP Info', description='Asset Wizard pro source information')


def dispose_type_properties():
    """
    Remove when unloading.
    """
    del Material.awp_source_info
    del Object.awp_source_info
    del Collection.awp_source_info
