# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration

import typing
from typing import List
import dataclasses
from dataclasses import dataclass, field

@dataclass(frozen=True)
class ChainProp:
    """Class to hold chain properties with (limited) type-checking"""
    name: str                   # mandatory
    groups: List[str]           # mandatory
    monGroups: List[str]        = field(default_factory = list)
    l1SeedThresholds: List[str] = field(default_factory = list)
    stream: List[str]           = field(default_factory = lambda : ['Main'])
    mergingStrategy: str        = 'auto'
    mergingOrder: List[str]     = field(default_factory = list)
    mergingOffset: int          = -1

    # currently we don't have a type-checker in LCG so we
    # implement a limited version ourselves:
    def _check_types(self):
        """Check field types"""
        for f in dataclasses.fields(self):
            actual_type = typing.get_origin(f.type) or f.type
            value = getattr(self, f.name)
            if actual_type == list:
                if value:
                    for el in value:
                        if not isinstance(el, typing.get_args(f.type)):
                            return f
            elif not isinstance(value, actual_type):
                return f
        return None

    def __post_init__(self):
        f = self._check_types()
        if f is not None:
            raise TypeError(f"Expected type of '{f.name}' to be {f.type}, "
                            f"got {repr(getattr(self, f.name))}")

if __name__=='__main__':
    ch = ChainProp(name='abc', groups=['g1'])