package com.chenyang.druid.sql.dialect.greenplum.ast.expr.constraint;

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLName;
import com.chenyang.druid.sql.ast.statement.SQLColumnConstraint;
import com.chenyang.druid.sql.ast.statement.SQLConstraintImpl;
import com.chenyang.druid.sql.dialect.greenplum.ast.GPSQLObject;
import com.chenyang.druid.sql.dialect.greenplum.ast.GPSQLObjectImpl;
import com.chenyang.druid.sql.dialect.greenplum.visitor.GPASTVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class GPConstraint extends SQLConstraintImpl implements GPSQLObject, SQLColumnConstraint {
   private Boolean iNull;
   private Boolean notNull;
   private GPConstraintCheck check;
   private SQLExpr defValue;
   private GPUnique unique;
   private GPPrimaryKey primaryKey;
   private GPReference reference;
   private ConstraintType type;

   public void simplify() {
   }

   public Boolean getiNull() {
      return this.iNull;
   }

   public void setiNull(Boolean iNull) {
      this.iNull = iNull;
   }

   public Boolean getNotNull() {
      return this.notNull;
   }

   public void setNotNull(Boolean notNull) {
      this.notNull = notNull;
   }

   public GPConstraintCheck getCheck() {
      return this.check;
   }

   public void setCheck(GPConstraintCheck check) {
      this.check = check;
      check.setParent(this);
   }

   public SQLExpr getDefValue() {
      return this.defValue;
   }

   public void setDefValue(SQLExpr defValue) {
      this.defValue = defValue;
      defValue.setParent(this);
   }

   public GPUnique getUnique() {
      return this.unique;
   }

   public void setUnique(GPUnique unique) {
      this.unique = unique;
      unique.setParent(this);
   }

   public GPPrimaryKey getPrimaryKey() {
      return this.primaryKey;
   }

   public void setPrimaryKey(GPPrimaryKey primaryKey) {
      this.primaryKey = primaryKey;
      primaryKey.setParent(this);
   }

   public GPReference getReference() {
      return this.reference;
   }

   public void setReference(GPReference reference) {
      this.reference = reference;
      reference.setParent(this);
   }

   public ConstraintType getType() {
      return this.type;
   }

   public void setType(ConstraintType type) {
      this.type = type;
   }

   public void accept0(SQLASTVisitor visitor) {
      this.accept0((GPASTVisitor)visitor);
   }

   public void accept0(GPASTVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.name);
      }

      visitor.endVisit(this);
   }

   public GPConstraint clone() {
      GPConstraint c = new GPConstraint();
      c.setName(this.name.clone());
      c.iNull = this.iNull;
      c.notNull = this.notNull;
      if (this.check != null) {
         c.setCheck(this.check.clone());
      }

      if (this.defValue != null) {
         c.setDefValue(this.defValue.clone());
      }

      if (this.unique != null) {
         c.setUnique(this.unique.clone());
      }

      if (this.primaryKey != null) {
         c.setPrimaryKey(this.primaryKey.clone());
      }

      if (this.reference != null) {
         c.setReference(this.reference.clone());
      }

      c.type = this.type;
      return c;
   }

   public static class GPConstraintCheck extends GPSQLObjectImpl {
      SQLExpr expr;
      boolean noInherit;

      public SQLExpr getExpr() {
         return this.expr;
      }

      public void setExpr(SQLExpr expr) {
         this.expr = expr;
      }

      public boolean isNoInherit() {
         return this.noInherit;
      }

      public void setNoInherit(boolean noInherit) {
         this.noInherit = noInherit;
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((GPASTVisitor)visitor);
      }

      public void accept0(GPASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.expr);
         }

         visitor.endVisit(this);
      }

      public GPConstraintCheck clone() {
         GPConstraintCheck c = new GPConstraintCheck();
         c.setExpr(this.expr.clone());
         c.noInherit = this.noInherit;
         return c;
      }
   }

   public static class GPIndexParamaters extends GPSQLObjectImpl {
      private List<GPStorageParameter> parameters = new ArrayList();
      private SQLExpr tablespace;

      public SQLExpr getTablespace() {
         return this.tablespace;
      }

      public void setTablespace(SQLExpr tablespace) {
         this.tablespace = tablespace;
      }

      public List<GPStorageParameter> getParameters() {
         return this.parameters;
      }

      public void setParameters(List<GPStorageParameter> parameters) {
         this.parameters = parameters;
      }

      public void addParameter(GPStorageParameter parameter) {
         this.parameters.add(parameter);
         parameter.setParent(this);
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((GPASTVisitor)visitor);
      }

      public void accept0(GPASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.parameters);
            this.acceptChild(visitor, this.tablespace);
         }

         visitor.endVisit(this);
      }

      public GPIndexParamaters clone() {
         GPIndexParamaters c = new GPIndexParamaters();
         if (this.parameters != null && this.parameters.size() > 0) {
            for(GPStorageParameter parameter : this.parameters) {
               c.addParameter(parameter.clone());
            }
         }

         if (this.tablespace != null) {
            c.setTablespace(this.tablespace.clone());
         }

         return c;
      }
   }

   public static class GPUnique extends GPSQLObjectImpl {
      protected List<SQLName> columns = new ArrayList();
      protected GPIndexParamaters indexParamaters;

      public List<SQLName> getColumns() {
         return this.columns;
      }

      public void setColumns(List<SQLName> columns) {
         this.columns = columns;
      }

      public GPIndexParamaters getIndexParamaters() {
         return this.indexParamaters;
      }

      public void setIndexParamaters(GPIndexParamaters indexParamaters) {
         this.indexParamaters = indexParamaters;
      }

      public void addColumn(SQLName column) {
         this.columns.add(column);
         column.setParent(this);
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((GPASTVisitor)visitor);
      }

      public void accept0(GPASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.columns);
            this.acceptChild(visitor, this.indexParamaters);
         }

         visitor.endVisit(this);
      }

      public GPUnique clone() {
         GPUnique c = new GPUnique();
         if (this.columns != null && this.columns.size() > 0) {
            for(SQLName column : this.columns) {
               c.addColumn(column);
            }
         }

         if (this.indexParamaters != null) {
            c.setIndexParamaters(this.indexParamaters.clone());
         }

         return c;
      }
   }

   public static class GPPrimaryKey extends GPUnique {
      public GPPrimaryKey clone() {
         GPPrimaryKey c = new GPPrimaryKey();
         if (this.columns != null && this.columns.size() > 0) {
            for(SQLName column : this.columns) {
               c.addColumn(column);
            }
         }

         if (this.indexParamaters != null) {
            c.setIndexParamaters(this.indexParamaters.clone());
         }

         return c;
      }
   }

   public static class GPForeignKey extends GPSQLObjectImpl {
      private List<SQLName> columns = new ArrayList();
      protected GPReference reference;

      public GPReference getReference() {
         return this.reference;
      }

      public void setReference(GPReference reference) {
         this.reference = reference;
      }

      public List<SQLName> getColumns() {
         return this.columns;
      }

      public void setColumns(List<SQLName> columns) {
         this.columns = columns;
      }

      public void addColumn(SQLName column) {
         this.columns.add(column);
         column.setParent(this);
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((GPASTVisitor)visitor);
      }

      public void accept0(GPASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.columns);
            this.acceptChild(visitor, this.reference);
         }

         visitor.endVisit(this);
      }

      public GPForeignKey clone() {
         GPForeignKey c = new GPForeignKey();
         if (this.columns != null && this.columns.size() > 0) {
            for(SQLName column : this.columns) {
               c.addColumn(column);
            }
         }

         if (this.reference != null) {
            c.setReference(this.reference.clone());
         }

         return c;
      }
   }

   public static class GPReference extends GPSQLObjectImpl {
      private SQLExpr refTable;
      private List<SQLExpr> columns = new ArrayList();
      private MatchType matchType;
      private KeyAction deleteAction;
      private KeyAction updateAction;

      public SQLExpr getRefTable() {
         return this.refTable;
      }

      public void setRefTable(SQLExpr refTable) {
         this.refTable = refTable;
         refTable.setParent(this);
      }

      public void addColumn(SQLExpr column) {
         this.columns.add(column);
         column.setParent(this);
      }

      public List<SQLExpr> getColumns() {
         return this.columns;
      }

      public void setColumns(List<SQLExpr> columns) {
         this.columns = columns;
      }

      public MatchType getMatchType() {
         return this.matchType;
      }

      public void setMatchType(MatchType matchType) {
         this.matchType = matchType;
      }

      public KeyAction getDeleteAction() {
         return this.deleteAction;
      }

      public void setDeleteAction(KeyAction deleteAction) {
         this.deleteAction = deleteAction;
      }

      public KeyAction getUpdateAction() {
         return this.updateAction;
      }

      public void setUpdateAction(KeyAction updateAction) {
         this.updateAction = updateAction;
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((GPASTVisitor)visitor);
      }

      public void accept0(GPASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.refTable);
            this.acceptChild(visitor, this.columns);
         }

         visitor.endVisit(this);
      }

      public GPReference clone() {
         GPReference c = new GPReference();
         c.setRefTable(this.refTable.clone());
         if (this.columns != null && this.columns.size() > 0) {
            for(SQLExpr column : this.columns) {
               c.addColumn(column.clone());
            }
         }

         c.matchType = this.matchType;
         c.deleteAction = this.deleteAction;
         c.updateAction = this.updateAction;
         return c;
      }

      public static enum MatchType {
         full,
         partial,
         simple;
      }

      public static enum KeyAction {
         onDelete,
         onUpdate,
         noAction,
         restrict,
         cascade,
         setNull,
         setDefault;
      }
   }

   public static enum ConstraintType {
      deferrable,
      notDeferrable,
      initiallyDeferred,
      initiallyImmediate;
   }
}
