package org.exoplatform.cs.dto;

import java.lang.reflect.Constructor;

import lombok.Data;

import org.apache.commons.lang3.StringUtils;

import org.exoplatform.cs.entity.ASTypeEntity;
import org.exoplatform.cs.entity.DBTypeEntity;
import org.exoplatform.cs.entity.EnvTypeEntity;
import org.exoplatform.cs.entity.JVMTypeEntity;
import org.exoplatform.cs.entity.OSTypeEntity;
import org.exoplatform.cs.entity.SSOTypeEntity;
import org.exoplatform.cs.entity.TypeEntity;

@Data
public class TypeDTO {

  String  type;

  String  label;

  long    id;

  boolean other;

  public static TypeDTO getDTOFromEntity(TypeEntity typeEntity) {
    if (typeEntity == null) {
      return null;
    }
    String type = getTypeFromClass(typeEntity.getClass());
    if (type == null) {
      return null;
    }
    TypeDTO typeDTO = new TypeDTO();
    typeDTO.setId(typeEntity.getId());
    typeDTO.setLabel(typeEntity.getLabel());
    typeDTO.setOther(typeEntity.getOther() != null && typeEntity.getOther());
    typeDTO.setType(type);
    return typeDTO;
  }

  public static TypeEntity getEntityFromDTO(TypeDTO typeDTO) {
    if (typeDTO == null) {
      return null;
    }
    Class<? extends TypeEntity> typeClass = getTypeFromString(typeDTO.getType());
    if (typeClass == null) {
      return null;
    }
    TypeEntity typeEntity = null;
    try {
      Constructor<? extends TypeEntity> constructor = typeClass.getConstructor(Long.class, String.class, Boolean.class);
      typeEntity = constructor.newInstance(typeDTO.getId(), typeDTO.getLabel(), typeDTO.isOther());
    } catch (Exception e) {
      throw new IllegalStateException("Error when parsing type entity from dto: " + typeDTO, e);
    }
    return typeEntity;
  }

  public static String getTypeFromClass(Class<? extends TypeEntity> type) {
    if (type == null) {
      return null;
    } else if (type.equals(JVMTypeEntity.class)) {
      return JVMTypeEntity.TYPE_NAME;
    } else if (type.equals(OSTypeEntity.class)) {
      return OSTypeEntity.TYPE_NAME;
    } else if (type.equals(ASTypeEntity.class)) {
      return ASTypeEntity.TYPE_NAME;
    } else if (type.equals(DBTypeEntity.class)) {
      return DBTypeEntity.TYPE_NAME;
    } else if (type.equals(SSOTypeEntity.class)) {
      return SSOTypeEntity.TYPE_NAME;
    } else if (type.equals(EnvTypeEntity.class)) {
      return EnvTypeEntity.TYPE_NAME;
    }
    return null;
  }

  public static Class<? extends TypeEntity> getTypeFromString(String type) {
    if (StringUtils.isBlank(type)) {
      return null;
    } else if (type.equals(JVMTypeEntity.TYPE_NAME)) {
      return JVMTypeEntity.class;
    } else if (type.equals(OSTypeEntity.TYPE_NAME)) {
      return OSTypeEntity.class;
    } else if (type.equals(ASTypeEntity.TYPE_NAME)) {
      return ASTypeEntity.class;
    } else if (type.equals(DBTypeEntity.TYPE_NAME)) {
      return DBTypeEntity.class;
    } else if (type.equals(SSOTypeEntity.TYPE_NAME)) {
      return SSOTypeEntity.class;
    } else if (type.equals(EnvTypeEntity.TYPE_NAME)) {
      return EnvTypeEntity.class;
    }
    return null;
  }
}
