package com.chenyang.druid.sql.dialect.spark.ast.statement;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.ast.statement.SQLAssignItem;
import com.chenyang.druid.sql.ast.statement.SQLInsertStatement;
import com.chenyang.druid.sql.dialect.spark.ast.SparkSqlExprImpl;
import com.chenyang.druid.sql.dialect.spark.ast.SparkSqlObject;
import com.chenyang.druid.sql.dialect.spark.ast.expr.HiveRowFormat;
import com.chenyang.druid.sql.dialect.spark.visitor.SparkVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;
import util.sqlparse.visitor.common.Objects;

public class SparkInsertStatement extends SQLInsertStatement implements SparkSqlObject {
   private SQLExpr queryTable;
   private SQLExpr fromTable;
   private boolean overwrite;
   private boolean directory;
   private boolean local;
   private SQLExpr directoryPath;
   private SparkFormat sparkFormat;
   private HiveRowFormat hiveFormat;
   private SQLExpr storedAs;

   public SparkInsertStatement() {
      this.dbType = DbType.spark;
   }

   public SQLExpr getQueryTable() {
      return this.queryTable;
   }

   public void setQueryTable(SQLExpr queryTable) {
      this.queryTable = queryTable;
      if (queryTable != null) {
         queryTable.setParent(this);
      }

   }

   public SQLExpr getFromTable() {
      return this.fromTable;
   }

   public void setFromTable(SQLExpr fromTable) {
      this.fromTable = fromTable;
      if (fromTable != null) {
         fromTable.setParent(this);
      }

   }

   public boolean isLocal() {
      return this.local;
   }

   public void setLocal(boolean local) {
      this.local = local;
   }

   public boolean isOverwrite() {
      return this.overwrite;
   }

   public boolean isDirectory() {
      return this.directory;
   }

   public void setDirectory(boolean directory) {
      this.directory = directory;
   }

   public SQLExpr getDirectoryPath() {
      return this.directoryPath;
   }

   public void setDirectoryPath(SQLExpr directoryPath) {
      this.directoryPath = directoryPath;
      directoryPath.setParent(this);
   }

   public SparkFormat getSparkFormat() {
      return this.sparkFormat;
   }

   public void setSparkFormat(SparkFormat sparkFormat) {
      this.sparkFormat = sparkFormat;
      sparkFormat.setParent(this);
   }

   public HiveRowFormat getHiveFormat() {
      return this.hiveFormat;
   }

   public void setHiveFormat(HiveRowFormat hiveFormat) {
      this.hiveFormat = hiveFormat;
      hiveFormat.setParent(this);
   }

   public void setOverwrite(boolean overwrite) {
      this.overwrite = overwrite;
   }

   public SQLExpr getStoredAs() {
      return this.storedAs;
   }

   public void setStoredAs(SQLExpr storedAs) {
      this.storedAs = storedAs;
   }

   public void cloneTo(SparkInsertStatement x) {
      super.cloneTo(x);
      x.overwrite = this.overwrite;
      x.directory = this.directory;
      x.local = this.local;
      if (this.directoryPath != null) {
         x.directoryPath = this.directoryPath.clone();
      }

      if (this.hiveFormat != null) {
         x.hiveFormat = this.hiveFormat.clone();
      }

      if (this.storedAs != null) {
         x.storedAs = this.storedAs.clone();
      }

      if (this.sparkFormat != null) {
         x.sparkFormat = this.sparkFormat.clone();
      }

      if (this.queryTable != null) {
         x.queryTable = this.queryTable.clone();
      }

      if (this.fromTable != null) {
         x.fromTable = this.fromTable.clone();
      }

   }

   public SparkInsertStatement clone() {
      SparkInsertStatement x = new SparkInsertStatement();
      this.cloneTo(x);
      return x;
   }

   protected void accept0(SQLASTVisitor visitor) {
      this.accept0((SparkVisitor)visitor);
   }

   public List<SQLObject> getChildren() {
      List<SQLObject> children = new ArrayList();
      if (this.sparkFormat != null) {
         children.add(this.sparkFormat);
      }

      if (this.hiveFormat != null) {
         children.add(this.hiveFormat);
      }

      if (this.storedAs != null) {
         children.add(this.storedAs);
      }

      children.add(this.tableSource);
      children.addAll(this.columns);
      children.addAll(this.valuesList);
      if (this.fromTable != null) {
         children.add(this.fromTable);
      }

      if (this.queryTable != null) {
         children.add(this.queryTable);
      }

      if (this.query != null) {
         children.add(this.query);
      }

      return children;
   }

   public String toString() {
      return SQLUtils.toSQLString(this, (DbType)this.dbType);
   }

   public void accept0(SparkVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.directoryPath);
         this.acceptChild(visitor, this.sparkFormat);
         this.acceptChild(visitor, this.hiveFormat);
         this.acceptChild(visitor, this.storedAs);
         this.acceptChild(visitor, this.tableSource);
         this.acceptChild(visitor, this.columns);
         this.acceptChild(visitor, this.valuesList);
         this.acceptChild(visitor, this.queryTable);
         this.acceptChild(visitor, this.fromTable);
         this.acceptChild(visitor, this.query);
      }

      visitor.endVisit(this);
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         SparkInsertStatement that = (SparkInsertStatement)o;
         return this.overwrite == that.overwrite && this.directory == that.directory && this.local == that.local && Objects.equals(this.queryTable, that.queryTable) && Objects.equals(this.fromTable, that.fromTable) && Objects.equals(this.directoryPath, that.directoryPath) && Objects.equals(this.sparkFormat, that.sparkFormat) && Objects.equals(this.hiveFormat, that.hiveFormat) && Objects.equals(this.storedAs, that.storedAs);
      } else {
         return false;
      }
   }

   public int hashCode() {
      return Objects.hash(this.queryTable, this.fromTable, this.overwrite, this.directory, this.local, this.directoryPath, this.sparkFormat, this.hiveFormat, this.storedAs);
   }

   public static class SparkFormat extends SparkSqlExprImpl {
      private SQLExpr fileFormat;
      private List<SQLAssignItem> options = new ArrayList();

      public SQLExpr getFileFormat() {
         return this.fileFormat;
      }

      public void setFileFormat(SQLExpr fileFormat) {
         this.fileFormat = fileFormat;
         fileFormat.setParent(this);
      }

      public void addOption(SQLAssignItem item) {
         this.options.add(item);
         item.setParent(this);
      }

      public List<SQLAssignItem> getOptions() {
         return this.options;
      }

      public void setOptions(List<SQLAssignItem> options) {
         this.options = options;
      }

      public SparkFormat clone() {
         SparkFormat e = new SparkFormat();
         e.fileFormat = this.fileFormat.clone();

         for(SQLAssignItem option : this.options) {
            e.options.add(option.clone());
         }

         return e;
      }

      public List<SQLObject> getChildren() {
         List<SQLObject> list = new ArrayList();
         list.add(this.fileFormat);
         list.addAll(this.options);
         return list;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.fileFormat);
            this.acceptChild(v, this.options);
         }

         v.endVisit(this);
      }

      public boolean equals(Object o) {
         if (this == o) {
            return true;
         } else if (o != null && this.getClass() == o.getClass()) {
            SparkFormat that = (SparkFormat)o;
            return Objects.equals(this.fileFormat, that.fileFormat) && Objects.equals(this.options, that.options);
         } else {
            return false;
         }
      }

      public int hashCode() {
         return Objects.hash(this.fileFormat, this.options);
      }
   }
}
