/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.sql.command;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.ignite.internal.processors.bulkload.BulkLoadAckClientParameters;
import org.apache.ignite.internal.processors.bulkload.BulkLoadCsvFormat;
import org.apache.ignite.internal.processors.bulkload.BulkLoadFormat;
import org.apache.ignite.internal.sql.SqlKeyword;
import org.apache.ignite.internal.sql.SqlLexer;
import org.apache.ignite.internal.sql.SqlLexerTokenType;
import org.apache.ignite.internal.util.typedef.internal.S;
import static org.apache.ignite.internal.sql.SqlParserUtils.error;
import static org.apache.ignite.internal.sql.SqlParserUtils.errorUnexpectedToken;
import static org.apache.ignite.internal.sql.SqlParserUtils.parseBoolean;
import static org.apache.ignite.internal.sql.SqlParserUtils.parseIdentifier;
import static org.apache.ignite.internal.sql.SqlParserUtils.parseInt;
import static org.apache.ignite.internal.sql.SqlParserUtils.parseQualifiedIdentifier;
import static org.apache.ignite.internal.sql.SqlParserUtils.parseString;
import static org.apache.ignite.internal.sql.SqlParserUtils.skipCommaOrRightParenthesis;
import static org.apache.ignite.internal.sql.SqlParserUtils.skipIfMatches;
import static org.apache.ignite.internal.sql.SqlParserUtils.skipIfMatchesKeyword;

/**
 * A parser for a COPY command (called 'bulk load' in the code, since word 'copy' is too generic).
 */
public class SqlBulkLoadCommand implements SqlCommand {
    /** Local file name to send from client to server. */
    private String locFileName;

    /** Schema name + table name. */
    private SqlQualifiedName tblQName;

    /** User-specified list of columns. */
    private List<String> cols;

    /** File format. */
    private BulkLoadFormat inputFormat;

    /** Packet size (size of portion of a file sent in each sub-request). */
    private Integer packetSize;

    /**
     * Parses the command.
     *
     * @param lex The lexer.
     * @return The parsed command object.
     */
    @Override public SqlCommand parse(SqlLexer lex) {
        skipIfMatchesKeyword(lex, SqlKeyword.FROM); // COPY keyword is already parsed

        parseFileName(lex);

        parseTableName(lex);

        parseColumns(lex);

        parseFormat(lex);

        parseParameters(lex);

        return this;
    }

    /**
     * Parses the file name.
     *
     * @param lex The lexer.
     */
    private void parseFileName(SqlLexer lex) {
        if (lex.lookAhead().tokenType() != SqlLexerTokenType.STRING)
            throw errorUnexpectedToken(lex.lookAhead(), "[file name: string]");

        lex.shift();

        locFileName = lex.token();
    }

    /**
     * Parses the schema and table names.
     *
     * @param lex The lexer.
     */
    private void parseTableName(SqlLexer lex) {
        skipIfMatchesKeyword(lex, SqlKeyword.INTO);

        tblQName = parseQualifiedIdentifier(lex);
    }

    /**
     * Parses the list of columns.
     *
     * @param lex The lexer.
     */
    private void parseColumns(SqlLexer lex) {
        skipIfMatches(lex, SqlLexerTokenType.PARENTHESIS_LEFT);

        cols = new ArrayList<>();

        do {
            cols.add(parseColumn(lex));
        }
        while (!skipCommaOrRightParenthesis(lex));
    }

    /**
     * Parses column clause.
     *
     * @param lex The lexer.
     * @return The column name.
     */
    private String parseColumn(SqlLexer lex) {
        return parseIdentifier(lex);
    }

    /**
     * Parses the format clause.
     *
     * @param lex The lexer.
     */
    private void parseFormat(SqlLexer lex) {
        skipIfMatchesKeyword(lex, SqlKeyword.FORMAT);

        String name = parseIdentifier(lex);

        switch (name.toUpperCase()) {
            case BulkLoadCsvFormat.NAME:
                BulkLoadCsvFormat fmt = new BulkLoadCsvFormat();

                // IGNITE-7537 will introduce user-defined values
                fmt.lineSeparator(BulkLoadCsvFormat.DEFAULT_LINE_SEPARATOR);
                fmt.fieldSeparator(BulkLoadCsvFormat.DEFAULT_FIELD_SEPARATOR);
                fmt.quoteChars(BulkLoadCsvFormat.DEFAULT_QUOTE_CHARS);
                fmt.commentChars(BulkLoadCsvFormat.DEFAULT_COMMENT_CHARS);
                fmt.escapeChars(BulkLoadCsvFormat.DEFAULT_ESCAPE_CHARS);
                fmt.nullString(BulkLoadCsvFormat.DEFAULT_NULL_STRING);
                fmt.trim(BulkLoadCsvFormat.DEFAULT_TRIM_SPACES);

                parseCsvOptions(lex, fmt);

                validateCsvParserFormat(lex, fmt);

                inputFormat = fmt;

                break;

            default:
                throw error(lex, "Unknown format name: " + name +
                    ". Currently supported format is " + BulkLoadCsvFormat.NAME);
        }
    }

    /**
     * Parses CSV format options.
     *
     * @param lex The lexer.
     * @param format CSV format object to configure.
     */
    private void parseCsvOptions(SqlLexer lex, BulkLoadCsvFormat format) {
        while (lex.lookAhead().tokenType() == SqlLexerTokenType.DEFAULT) {
            switch (lex.lookAhead().token()) {
                case SqlKeyword.CHARSET: {
                    lex.shift();

                    String charsetName = parseString(lex);

                    format.inputCharsetName(charsetName);

                    break;
                }

                case SqlKeyword.DELIMITER: {
                    lex.shift();

                    String delimiter = parseString(lex);

                    format.fieldSeparator(Pattern.compile(delimiter));

                    break;
                }

                case SqlKeyword.TRIM: {
                    lex.shift();

                    Boolean trim = parseBoolean(lex);

                    format.trim(trim);

                    break;
                }

                case SqlKeyword.NULLSTRING: {
                    lex.shift();

                    String nullString = parseString(lex);

                    format.nullString(nullString);

                    break;
                }

                default:
                    return;
            }
        }
    }

    /**
     * Parses the optional parameters.
     *
     * @param lex The lexer.
     */
    private void parseParameters(SqlLexer lex) {
        while (lex.lookAhead().tokenType() == SqlLexerTokenType.DEFAULT) {
            switch (lex.lookAhead().token()) {
                case SqlKeyword.PACKET_SIZE:
                    lex.shift();

                    int size = parseInt(lex);

                    if (!BulkLoadAckClientParameters.isValidPacketSize(size))
                        throw error(lex, BulkLoadAckClientParameters.packetSizeErrorMesssage(size));

                    packetSize = size;

                    break;

                default:
                    return;
            }
        }
    }

    /**
     * Parses the optional parameters.
     *
     * @param lex The lexer.
     * @param format CSV format object to validate.
     */
    private void validateCsvParserFormat(SqlLexer lex, BulkLoadCsvFormat format) {
        String delimiter = format.fieldSeparator().toString();
        String quoteChars = format.quoteChars();

        if (delimiter.length() > 1 || quoteChars.length() > 1)
            throw error(lex, "Delimiter or quote chars must consist of single character: delim is '" + delimiter
                + "', quote char is '" + quoteChars + "'");

        if (delimiter.equals(quoteChars))
            throw error(lex, "Invalid delimiter or quote chars: delim is '" + delimiter
                + "', quote char is '" + quoteChars + "'");
    }

    /**
     * Returns the schemaName.
     *
     * @return schemaName.
     */
    @Override public String schemaName() {
        return tblQName.schemaName();
    }

    /** {@inheritDoc} */
    @Override public void schemaName(String schemaName) {
        tblQName.schemaName(schemaName);
    }

    /**
     * Returns the table name.
     *
     * @return The table name
     */
    public String tableName() {
        return tblQName.name();
    }

    /**
     * Sets the table name
     *
     * @param tblName The table name.
     */
    public void tableName(String tblName) {
        tblQName.name(tblName);
    }

    /**
     * Returns the local file name.
     *
     * @return The local file name.
     */
    public String localFileName() {
        return locFileName;
    }

    /**
     * Sets the local file name.
     *
     * @param locFileName The local file name.
     */
    public void localFileName(String locFileName) {
        this.locFileName = locFileName;
    }

    /**
     * Returns the list of columns.
     *
     * @return The list of columns.
     */
    public List<String> columns() {
        return cols;
    }

    /**
     * Returns the input file format.
     *
     * @return The input file format.
     */
    public BulkLoadFormat inputFormat() {
        return inputFormat;
    }

    /**
     * Returns the packet size.
     *
     * @return The packet size.
     */
    public Integer packetSize() {
        return packetSize;
    }

    /**
     * Sets the packet size.
     *
     * @param packetSize The packet size.
     */
    public void packetSize(int packetSize) {
        this.packetSize = packetSize;
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(SqlBulkLoadCommand.class, this);
    }
}
