package net.northking.cctp.maven.analyse.entity;

import net.northking.cctp.maven.analyse.util.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JAVA类对象
 *
 * @author 谢秀松
 * @since 1.0
 */
public final class JavaClassRef
{
  /**
   * 表名
   */
  private String tableName;
  /**
   * 所在包名
   */
  private String packageName;

  /**
   * 导入的包集合
   */
  private List<String> importPackages;

  /**
   * JAVA类名
   */
  private String className;

  /**
   * 句柄名称
   */
  private String refName;

  /**
   * 注释
   */
  private String comment;

  /**
   * 属性集合
   */
  private List<AttributesRef> attributes = new ArrayList<AttributesRef>();

  /**
   * 外键属性集合
   */
  private List<AttributesRef> fkAttributes = new ArrayList<AttributesRef>();

  /**
   * 属性Map结构
   */
  private Map<String, AttributesRef> attrMap = new HashMap<>();

  /**
   * 获取 packageName
   *
   * @return the value of packageName
   */
  public String getPackageName()
  {
    return packageName;
  }

  /**
   * 设置 packageName
   *
   * @param packageName packageName
   */
  public void setPackageName(final String packageName)
  {
    this.packageName = packageName;
  }

  /**
   * 获取 importPackages
   *
   * @return the value of importPackages
   */
  public List<String> getImportPackages()
  {
    return importPackages;
  }

  /**
   * 设置 importPackages
   *
   * @param importPackages importPackages
   */
  public void setImportPackages(final List<String> importPackages)
  {
    this.importPackages = importPackages;
  }

  /**
   * 获取 className
   *
   * @return the value of className
   */
  public String getClassName()
  {
    return className;
  }

  /**
   * 设置 className
   *
   * @param className className
   */
  public void setClassName(final String className)
  {
    this.className = className;
  }

  /**
   * 获取 refName
   *
   * @return the value of refName
   */
  public String getRefName()
  {
    return refName;
  }

  /**
   * 设置 refName
   *
   * @param refName refName
   */
  public void setRefName(final String refName)
  {
    this.refName = refName;
  }

  /**
   * 获取 comment
   *
   * @return the value of comment
   */
  public String getComment()
  {
    return comment;
  }

  /**
   * 设置 comment
   *
   * @param comment comment
   */
  public void setComment(final String comment)
  {
    this.comment = comment;
  }

  /**
   * 获取 attributes
   *
   * @return the value of attributes
   */
  public List<AttributesRef> getAttributes()
  {
    return attributes;
  }

  /**
   * 设置 attributes
   *
   * @param attributes attributes
   */
  public void setAttributes(final List<AttributesRef> attributes)
  {
    this.attributes = attributes;
  }

  /**
   * 获取 fkAttributes
   *
   * @return the value of fkAttributes
   */
  public List<AttributesRef> getFkAttributes()
  {
    return fkAttributes;
  }

  /**
   * 设置 fkAttributes
   *
   * @param fkAttributes fkAttributes
   */
  public void setFkAttributes(final List<AttributesRef> fkAttributes)
  {
    this.fkAttributes = fkAttributes;
  }

  /**
   * 获取 attrMap
   *
   * @return the value of attrMap
   */
  public Map<String, AttributesRef> getAttrMap()
  {
    return attrMap;
  }

  /**
   * 设置 attrMap
   *
   * @param attrMap attrMap
   */
  public void setAttrMap(final Map<String, AttributesRef> attrMap)
  {
    this.attrMap = attrMap;
  }

  /**
   * 添加属性
   *
   * @param attributesRef 属性
   */
  public void addAttributesRef(final AttributesRef attributesRef)
  {
    attributes.add(attributesRef);
  }

  public String getTableName()
  {
    return tableName;
  }

  public void setTableName(String tableName)
  {
    this.tableName = tableName;
  }

  /**
   * 根据数据库表构造JAVA类
   *
   * @param tableRef 数据库表
   */
  public JavaClassRef(final TableRef tableRef)
  {
    tableName = tableRef.getTableName();
    className = StringUtil.underlineToCamel(tableName);
    refName = StringUtil.toJavaRefName(className);
    comment = tableRef.getComment();
    this.initAttributes(tableRef);
  }

  /**
   * 初始化类的属性
   *
   * @param tableRef 数据库表
   */
  private void initAttributes(final TableRef tableRef)
  {
    // 数据库表的字段对应JAVA类的属性
    for (ColumnRef columnRef : tableRef.getColumns())
    {
      AttributesRef attributesRef = new AttributesRef(columnRef);
      columnRef.setAttributesRef(attributesRef);
      attributes.add(attributesRef);
      attrMap.put(attributesRef.getClassName(), attributesRef);
    }

  }

  private void extForeignKeyAttributes(TableRef tableRef)
  {
    // 数据库表的字段对应JAVA类的属性对象
    for (ForeignKeyRef foreignKeyRef : tableRef.getForeignKeys())
    {
      AttributesRef foreignAttr = new AttributesRef(foreignKeyRef);
      AttributesRef attributesRef = attrMap.get(StringUtil.underlineToCamel(foreignKeyRef.getFkColumnName()));
      if (attributesRef != null)
      {
        foreignAttr.setComment("ForeignKey: " + attributesRef.getComment());
      }
      fkAttributes.add(foreignAttr);
      attrMap.put(foreignAttr.getClassName(), foreignAttr);
    }
  }

  private void extDateAttributes(AttributesRef attributesRef)
  {
    // 日期类型的字段扩展 大于、小于、大于等于、小于等于
    if ("Date".equalsIgnoreCase(attributesRef.getJavaTypeName()))
    {
      AttributesRef lt = (AttributesRef) attributesRef.clone(); // 小于less than
      lt.setRefName(lt.getRefName() + "Lt");
      lt.setClassName(lt.getClassName() + "Lt");
      lt.setComment("小于(less than) " + lt.getComment());
      attributes.add(lt);
      AttributesRef le = (AttributesRef) attributesRef.clone(); // 小于等于less and equal
      le.setRefName(le.getRefName() + "Le");
      le.setClassName(le.getClassName() + "Le");
      le.setComment("小于等于(less and equal) " + le.getComment());
      attributes.add(le);
      AttributesRef gt = (AttributesRef) attributesRef.clone(); // 大于great than
      gt.setRefName(gt.getRefName() + "Gt");
      gt.setClassName(gt.getClassName() + "Gt");
      gt.setComment("大于(great than) " + gt.getComment());
      attributes.add(gt);
      AttributesRef ge = (AttributesRef) attributesRef.clone(); // 大于等于great and equal
      ge.setRefName(ge.getRefName() + "Ge");
      ge.setClassName(ge.getClassName() + "Ge");
      ge.setComment("大于等于(great and equal) " + ge.getComment());
      attributes.add(ge);
    }
  }


  /**
   * 描述信息
   *
   * @return 描述信息
   */
  public String toString()
  {
    StringBuffer sb = new StringBuffer();
    sb.append("comment=" + comment + ", package=" + packageName + ", ClassName=" + className);
    sb.append("\r\n");
    for (AttributesRef attributesRef : attributes)
    {
      sb.append(attributesRef.toString());
      sb.append("\r\n");
    }
    return sb.toString();
  }
}
