'use strict';

import 'reflect-metadata';
import {manager} from './manager';
import {IBaseModelConstructor} from './interfaces';

const data_: WeakMap<IBaseModelConstructor, any> = new WeakMap();

function data(model) {
  if(!data_.has(model)) {
     data_.set(model, {
       properties: {},
       relations: {}
     });
  }
  return data_.get(model);
}

export function model(options?: any): ClassDecorator {
  return function(target: IBaseModelConstructor): IBaseModelConstructor | void {
    data(target).options = options;
    const data_ = data(target);
    manager.defineModel(target, data_.options, data_.properties, data_.relations);
    return target;
  }
}

export function property(options?: any): PropertyDecorator {
  return function(target: Object, propertyKey: string | symbol): void {
    const model: IBaseModelConstructor = <IBaseModelConstructor>target.constructor;
    data(model).properties[propertyKey] = options;
  }
}

export function relation(options?: any): PropertyDecorator {
  return function(target: Object, propertyKey: string | symbol): void {
    const model: IBaseModelConstructor = <IBaseModelConstructor>target.constructor;
    data(model).relations[propertyKey] = options;
  }
}