import is from '@pilotlab/is';
import { List, MapList } from '@pilotlab/collections';
import DataTypeDescriptions from './dataTypeDescriptions';


export interface IDataTypeDescription {
    src?:string;
    className:string;
    aliases?:string[];
    validator:(value:any) => boolean;
}

export class DataTypeDescription implements IDataTypeDescription {
    constructor(src:string, className:string, type:string, parentType:string, aliases:string[], validator:(value:any) => boolean) {
        this.src = src;
        this.type = type;
        this.validator = validator;
        this.p_descriptions = new List<DataTypeDescription>();
        this.aliases = [];
    }


    src:string;
    className:string;
    type:string;
    parentType:string;
    aliases:string[];
    validator:(value:any) => boolean;


    protected p_descriptions:List<DataTypeDescription>;


    validate(value:any):string {
        let type:string = '';

        for(let i = 0; i < this.p_descriptions.size; i++) {
            let typeDescription:DataTypeDescription = this.p_descriptions.item(i);
            type = typeDescription.validate(value);
            if (is.notEmpty(type, true)) break;
        }

        if (is.empty(type, true) && this.validate(value)) type = this.type;

        return type;
    }


    registerDataType(src:string, className:string, type:string, parentType:string, aliases:string[], validator:(value:any) => boolean):DataTypeDescription {
        if (is.empty(type, true) || is.empty(validator)) return;
        let typeDescription:DataTypeDescription = new DataTypeDescription(src, className, type, parentType, aliases, validator);
        this.p_descriptions.add(typeDescription);
        return typeDescription;
    }
}


export class DataTypes {
    constructor() {
        this.p_descriptions = new MapList<string, IDataTypeDescription>();

        DataTypeDescriptions.types.forEach((dataTypeDescription:IDataTypeDescription) => {
            console.log(`${dataTypeDescription.className}`);
            let parent:IDataTypeDescription;

            // if (is.notEmpty(dataTypeDescription.parentType)) {
            //     parent = this.p_descriptions.get(dataTypeDescription.parentType);
            // }
        });

        //
        // let isCollectionType = (value:any) => {
        //     return is.notEmpty(value) && (value instanceof AttributesBase || typeof value === 'object' || Array.isArray(value))
        // };
        //
        // let typeAny:DataTypeDescription = new DataTypeDescription('/', 'any', (value:any) => true);
        // typeAny.registerDataType('/', 'null', (value:any) => { return value === null; });
        // typeAny.registerDataType('/', 'undefined', (value:any) => { return typeof value === 'undefined' });
        // typeAny.registerDataType('/', 'boolean', (value:any) => { return typeof value === 'boolean' });
        // typeAny.registerDataType('/', 'number', (value:any) => { return is.number(value) });
        // typeAny.registerDataType('/', 'string', (value:any) => { return typeof value === 'string' });
        //
        // let typeCollection:DataTypeDescription = typeAny.registerDataType('/', 'collection', isCollectionType);
        // let typeColor:DataTypeDescription = typeCollection.registerDataType('/', 'color', (value:any) => {
        //     return (
        //         is.notEmpty(value) &&
        //         typeof value === 'object' &&
        //         value.hasOwnProperty('r') &&
        //         value.hasOwnProperty('g') &&
        //         value.hasOwnProperty('b')
        //     );
        // });
        //
        // let typePoint:DataTypeDescription = typeCollection.registerDataType('/', 'point', (value:any) => {
        //     return (
        //         is.notEmpty(value) &&
        //         typeof value === 'object' &&
        //         value.hasOwnProperty('x') &&
        //         value.hasOwnProperty('y')
        //     );
        // });
        //
        // let typePoint3d:DataTypeDescription = typePoint.registerDataType('/', 'point_3d', (value:any) => {
        //     return (
        //         is.notEmpty(value) &&
        //         value.hasOwnProperty('x') &&
        //         value.hasOwnProperty('y') &&
        //         value.hasOwnProperty('z')
        //     );
        // });
        //
        // let testValue:any;
        // console.log(`typeof: ${typeof testValue}`);
        // console.log(`data type: ${typeAny.validate(testValue)}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
    }


    protected p_descriptions:MapList<string, IDataTypeDescription>;
} // End class


export default DataTypes;
