package com.alibaba.druid.sql.dialect.mysql.visitor;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import java.util.ArrayList;
import java.util.List;

public class MySqlShowColumnOutpuVisitor extends MySqlOutputVisitor {
   public MySqlShowColumnOutpuVisitor(Appendable appender) {
      super(appender);
   }

   public boolean visit(MySqlCreateTableStatement x) {
      List<SQLColumnDefinition> columns = new ArrayList();
      List<String> dataTypes = new ArrayList();
      List<String> defaultValues = new ArrayList();
      int name_len = -1;
      int dataType_len = -1;
      int defaultVal_len = 7;
      int extra_len = 5;

      for(SQLTableElement element : x.getTableElementList()) {
         if (element instanceof SQLColumnDefinition) {
            SQLColumnDefinition column = (SQLColumnDefinition)element;
            columns.add(column);
            String name = SQLUtils.normalize(column.getName().getSimpleName());
            if (name_len < name.length()) {
               name_len = name.length();
            }

            String dataType = column.getDataType().getName();
            if (column.getDataType().getArguments().size() > 0) {
               dataType = dataType + "(";

               for(int i = 0; i < column.getDataType().getArguments().size(); ++i) {
                  if (i != 0) {
                     dataType = dataType + ",";
                  }

                  SQLExpr arg = (SQLExpr)column.getDataType().getArguments().get(i);
                  dataType = dataType + arg.toString();
               }

               dataType = dataType + ")";
            }

            if (dataType_len < dataType.length()) {
               dataType_len = dataType.length();
            }

            dataTypes.add(dataType);
            if (column.getDefaultExpr() == null) {
               defaultValues.add(null);
            } else {
               String defaultVal = SQLUtils.toMySqlString(column.getDefaultExpr());
               if (defaultVal.length() > 2 && defaultVal.charAt(0) == '\'' && defaultVal.charAt(defaultVal.length() - 1) == '\'') {
                  defaultVal = defaultVal.substring(1, defaultVal.length() - 1);
               }

               defaultValues.add(defaultVal);
               if (defaultVal_len < defaultVal.length()) {
                  defaultVal_len = defaultVal.length();
               }
            }

            if (column.isAutoIncrement()) {
               extra_len = "auto_increment".length();
            } else if (column.getOnUpdate() != null) {
               extra_len = "on update CURRENT_TIMESTAMP".length();
            }
         }
      }

      this.print("+-");
      this.print('-', name_len);
      this.print("-+-");
      this.print('-', dataType_len);
      this.print("-+------+-----+-");
      this.print('-', defaultVal_len);
      this.print("-+-");
      this.print('-', extra_len);
      this.print("-+\n");
      this.print("| ");
      this.print("Field", name_len, ' ');
      this.print(" | ");
      this.print("Type", dataType_len, ' ');
      this.print(" | Null | Key | ");
      this.print("Default", defaultVal_len, ' ');
      this.print(" | ");
      this.print("Extra", extra_len, ' ');
      this.print(" |\n");
      this.print("+-");
      this.print('-', name_len);
      this.print("-+-");
      this.print('-', dataType_len);
      this.print("-+------+-----+-");
      this.print('-', defaultVal_len);
      this.print("-+-");
      this.print('-', extra_len);
      this.print("-+\n");

      for(int i = 0; i < columns.size(); ++i) {
         SQLColumnDefinition column = (SQLColumnDefinition)columns.get(i);
         String name = SQLUtils.normalize(column.getName().getSimpleName());
         this.print("| ");
         this.print(name, name_len, ' ');
         this.print(" | ");
         this.print((String)dataTypes.get(i), dataType_len, ' ');
         this.print(" | ");
         if (column.containsNotNullConstaint()) {
            this.print("NO ");
         } else {
            this.print("YES");
         }

         this.print("  | ");
         MySqlUnique unique = null;
         if (x.isPrimaryColumn(name)) {
            this.print("PRI");
         } else if (x.isUNI(name)) {
            this.print("UNI");
         } else if (x.isMUL(name)) {
            this.print("MUL");
         } else {
            this.print("   ");
         }

         this.print(" | ");
         String defaultVal = (String)defaultValues.get(i);
         if (defaultVal == null) {
            this.print("NULL", defaultVal_len, ' ');
         } else {
            this.print(defaultVal, defaultVal_len, ' ');
         }

         this.print(" | ");
         if (column.isAutoIncrement()) {
            this.print("auto_increment", extra_len, ' ');
         } else if (column.getOnUpdate() != null) {
            this.print("on update CURRENT_TIMESTAMP", extra_len, ' ');
         } else {
            this.print(' ', extra_len);
         }

         this.print(" |");
         this.print("\n");
      }

      this.print("+-");
      this.print('-', name_len);
      this.print("-+-");
      this.print('-', dataType_len);
      this.print("-+------+-----+-");
      this.print('-', defaultVal_len);
      this.print("-+-");
      this.print('-', extra_len);
      this.print("-+\n");
      return false;
   }

   void print(char ch, int count) {
      for(int i = 0; i < count; ++i) {
         this.print(ch);
      }

   }

   void print(String text, int columnSize, char ch) {
      this.print(text);
      this.print(' ', columnSize - text.length());
   }
}
