package com.chenyang.druid.sql.dialect.postgresql.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.postgresql.ast.PGSQLObject;
import com.chenyang.druid.sql.dialect.postgresql.ast.PGSQLObjectImpl;
import com.chenyang.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class PGConstraint extends SQLConstraintImpl implements PGSQLObject, SQLColumnConstraint {
   private Boolean iNull;
   private Boolean notNull;
   private PGConstraintCheck check;
   private SQLExpr defValue;
   private PGUnique unique;
   private PGPrimaryKey primaryKey;
   private PGReference 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 PGConstraintCheck getCheck() {
      return this.check;
   }

   public void setCheck(PGConstraintCheck 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 PGUnique getUnique() {
      return this.unique;
   }

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

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

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

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

   public void setReference(PGReference 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((PGASTVisitor)visitor);
   }

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

      visitor.endVisit(this);
   }

   public PGConstraint clone() {
      PGConstraint c = new PGConstraint();
      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 PGConstraintCheck extends PGSQLObjectImpl {
      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((PGASTVisitor)visitor);
      }

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

         visitor.endVisit(this);
      }

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

   public static class PGIndexParamaters extends PGSQLObjectImpl {
      private List<PGStorageParameter> parameters = new ArrayList();
      private SQLExpr tablespace;

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

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

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

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

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

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

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

         visitor.endVisit(this);
      }

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

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

         return c;
      }
   }

   public static class PGUnique extends PGSQLObjectImpl {
      protected List<SQLName> columns = new ArrayList();
      protected PGIndexParamaters indexParamaters;

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

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

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

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

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

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

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

         visitor.endVisit(this);
      }

      public PGUnique clone() {
         PGUnique c = new PGUnique();
         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 PGPrimaryKey extends PGUnique {
      public PGPrimaryKey clone() {
         PGPrimaryKey c = new PGPrimaryKey();
         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 PGForeignKey extends PGSQLObjectImpl {
      private List<SQLName> columns = new ArrayList();
      protected PGReference reference;

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

      public void setReference(PGReference 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((PGASTVisitor)visitor);
      }

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

         visitor.endVisit(this);
      }

      public PGForeignKey clone() {
         PGForeignKey c = new PGForeignKey();
         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 PGReference extends PGSQLObjectImpl {
      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((PGASTVisitor)visitor);
      }

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

         visitor.endVisit(this);
      }

      public PGReference clone() {
         PGReference c = new PGReference();
         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;
   }
}
