package com.actiontech.dble.manager.dump;

import com.actiontech.dble.DbleServer;
import com.actiontech.dble.config.model.SchemaConfig;
import com.actiontech.dble.config.model.TableConfig;
import com.actiontech.dble.manager.dump.handler.DefaultHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author Baofengqi
 */
public final class DumpFileContext {

    // current schema
    private String schema;
    private String defaultDataNode;
    private Set<String> allDataNodes;

    // current table
    private String table;
    private TableConfig tableConfig;
    private int partitionColumnIndex = -1;
    private int incrementColumnIndex = -1;
    private DefaultHandler.TableType tableType = null;

    // other
    private boolean isSkip = false;
    private DumpFileWriter writer;
    private List<ErrorMsg> errors;
    private boolean needSkipError;
    private DumpFileConfig config;

    public DumpFileContext(DumpFileWriter writer, DumpFileConfig config) {
        this.writer = writer;
        this.errors = new ArrayList<>(10);
        this.config = config;
    }

    public String getSchema() {
        return schema;
    }

    public void setSchema(String schema) throws DumpException {
        SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(schema);
        if (schemaConfig == null) {
            throw new DumpException("schema[" + schema + "] doesn't exist in config.");
        }
        this.schema = schema;
        this.defaultDataNode = schemaConfig.getDataNode();
        this.allDataNodes = schemaConfig.getAllDataNodes();
        this.table = null;
    }

    void setDefaultSchema(SchemaConfig schemaConfig) {
        this.schema = schemaConfig.getName();
        this.defaultDataNode = schemaConfig.getDataNode();
        this.allDataNodes = schemaConfig.getAllDataNodes();
    }

    public boolean isSkipContext() {
        return this.isSkip;
    }

    public void setSkipContext(boolean skip) {
        this.isSkip = skip;
    }


    public String getDefaultDataNode() {
        return defaultDataNode;
    }

    public String getTable() {
        return table;
    }

    public void setTable(String table) throws DumpException {
        if (table == null) {
            this.tableConfig = null;
            return;
        }
        if (table.equalsIgnoreCase(this.table)) {
            return;
        }
        this.table = table;
        this.isSkip = false;
        this.partitionColumnIndex = -1;
        this.incrementColumnIndex = -1;
        this.needSkipError = false;
        if (this.schema == null) {
            throw new DumpException("Can't tell which schema the table[" + table + "] belongs to.");
        }
        this.tableConfig = DbleServer.getInstance().getConfig().getSchemas().get(schema).getTables().get(table);
        if (this.tableConfig == null && this.defaultDataNode == null) {
            throw new DumpException("schema " + schema + " has no default node.");
        }
        if (this.tableConfig != null && this.tableConfig.getParentTC() != null) {
            throw new DumpException("can't process child table, skip.");
        }
        if (this.tableConfig != null) {
            if (tableConfig.getPartitionColumn() != null) {
                this.tableType = DefaultHandler.TableType.SHARDING;
                return;
            } else if (tableConfig.isAutoIncrement()) {
                this.tableType = DefaultHandler.TableType.INCREMENT;
                return;
            }
        }
        this.tableType = DefaultHandler.TableType.DEFAULT;
    }

    public DefaultHandler.TableType getTableType() {
        return tableType;
    }

    public TableConfig getTableConfig() {
        return tableConfig;
    }

    public void setTableConfig(TableConfig tableConfig) {
        this.tableConfig = tableConfig;
    }

    public int getPartitionColumnIndex() {
        return partitionColumnIndex;
    }

    public void setPartitionColumnIndex(int partitionColumnIndex) {
        this.partitionColumnIndex = partitionColumnIndex;
    }

    public int getIncrementColumnIndex() {
        return incrementColumnIndex;
    }

    public void setIncrementColumnIndex(int incrementColumnIndex) {
        this.incrementColumnIndex = incrementColumnIndex;
    }

    public DumpFileWriter getWriter() {
        return writer;
    }

    public void addError(String error) {
        this.errors.add(new ErrorMsg(schema + "-" + table, error));
    }

    public List<ErrorMsg> getErrors() {
        return errors;
    }

    public boolean isNeedSkipError() {
        return needSkipError;
    }

    public void setNeedSkipError(boolean needSkipError) {
        this.needSkipError = needSkipError;
    }

    public DumpFileConfig getConfig() {
        return config;
    }

    public Set<String> getAllDataNodes() {
        return allDataNodes;
    }

}
