/*
 * 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.
 */

#include "cli/run_cli.h"

#include <cstdio>
#include <set>

#include "cli/cli_args.h"
#include "cli/exit_codes.h"
#include "commands/commands.h"
#include "format/output_format.h"
#include "reader/tsfile_reader.h"

#ifdef _WIN32
#include <io.h>
#define TSFILE_ISATTY _isatty
#define TSFILE_FILENO _fileno
#else
#include <unistd.h>
#define TSFILE_ISATTY isatty
#define TSFILE_FILENO fileno
#endif

#ifndef TSFILE_CLI_VERSION
#define TSFILE_CLI_VERSION "unknown"
#endif

namespace tsfile_cli {
namespace {

void print_usage(std::ostream& os) {
    os << "Usage: tsfile-cli <command> [options] <file.tsfile>\n"
          "Commands:\n"
          "  ls       list devices (tree) or tables (table)\n"
          "  schema   per-measurement data type/encoding/compression\n"
          "  meta     file metadata summary\n"
          "  stats    per-series count, time range, "
          "min/max/first/last/sum\n"
          "  head     first N rows (use -n)\n"
          "  cat      all rows of a device/table\n"
          "  count    number of rows (per series, plus a total)\n"
          "  sample   deterministic sample rows (use -n and --seed)\n"
          "  write    import CSV/TSV rows into a new table tsfile "
          "(--table, --columns, -o)\n"
          "Options:\n"
          "  -f, --format csv|tsv|json|table  output format "
          "(default: table on a TTY, tsv when piped)\n"
          "  -d, --device <name>      restrict to one device (tree model)\n"
          "  -t, --table <name>       restrict to one table (table model)\n"
          "  -m, --measurements a,b   project only these measurements\n"
          "  -n, --limit N            max rows (head/cat/sample)\n"
          "      --offset N           skip N rows before emitting\n"
          "      --start <ms>         inclusive lower time bound\n"
          "      --end <ms>           inclusive upper time bound\n"
          "      --seed N             RNG seed for sample\n"
          "      --tag-filter C OP V   table TAG predicate; OP is "
          "eq|neq|lt|lteq|gt|gteq|regexp|not-regexp\n"
          "      --tag-between C L U   table TAG predicate: L <= C <= U\n"
          "      --tag-not-between C L U  table TAG predicate outside [L,U]\n"
          "      --no-header          omit the header row\n"
          "      --model tree|table   force the data model (else auto)\n"
          "  -h, --help               print this help\n"
          "      --version            print version\n"
          "Write options:\n"
          "      --table <name>       target table name (required)\n"
          "      --columns SPEC       column spec name:TYPE:tag|field,... "
          "(required)\n"
          "  -o, --output <file>      destination .tsfile (required)\n"
          "      --header-match       require the input header to match "
          "--columns\n"
          "  -v, --verbose            report rows written to stderr\n";
}

bool is_known_command(const std::string& c) {
    static const std::set<std::string> kCmds = {"ls",    "schema", "meta",
                                                "stats", "head",   "cat",
                                                "count", "sample", "write"};
    return kCmds.find(c) != kCmds.end();
}

bool validate_command_flags(const ParsedArgs& p, std::ostream& err) {
    if (p.has_seed && p.command != "sample") {
        err << "Error: --seed is only valid for sample\n";
        return false;
    }
    if (p.command == "sample" && p.offset != 0) {
        err << "Error: --offset is not valid for sample\n";
        return false;
    }
    if (!p.device.empty() && !p.table.empty()) {
        err << "Error: -d/--device and -t/--table cannot be used together\n";
        return false;
    }
    if (p.limit < -1) {
        err << "Error: -n/--limit must be >= -1\n";
        return false;
    }
    if (p.offset < 0) {
        err << "Error: --offset must be >= 0\n";
        return false;
    }
    if (p.has_start && p.has_end && p.start > p.end) {
        err << "Error: --start must be <= --end\n";
        return false;
    }
    return true;
}

bool validate_write_flags(const ParsedArgs& p, std::ostream& err) {
    if (p.table.empty()) {
        err << "Error: write requires -t/--table\n";
        return false;
    }
    if (p.columns.empty()) {
        err << "Error: write requires --columns\n";
        return false;
    }
    if (p.output.empty()) {
        err << "Error: write requires -o/--output\n";
        return false;
    }
    if (p.format == ParsedArgs::Format::kJson ||
        p.format == ParsedArgs::Format::kTable) {
        err << "Error: write input format must be csv or tsv\n";
        return false;
    }
    if (p.no_header && p.header_match) {
        err << "Error: --header-match cannot be combined with --no-header\n";
        return false;
    }
    if (p.has_tag_filter) {
        err << "Error: tag filter flags are not valid for write\n";
        return false;
    }
    // Name the offending flag so the user does not have to guess which of
    // the read-only options triggered the rejection.
    if (!p.measurements.empty()) {
        err << "Error: -m/--measurements is not valid for write\n";
        return false;
    }
    if (!p.device.empty()) {
        err << "Error: -d/--device is not valid for write\n";
        return false;
    }
    if (p.has_start || p.has_end) {
        err << "Error: --start/--end are not valid for write\n";
        return false;
    }
    if (p.has_seed) {
        err << "Error: --seed is not valid for write\n";
        return false;
    }
    if (p.limit != -1) {
        err << "Error: -n/--limit is not valid for write\n";
        return false;
    }
    if (p.offset != 0) {
        err << "Error: --offset is not valid for write\n";
        return false;
    }
    if (!p.model.empty()) {
        err << "Error: --model is not valid for write\n";
        return false;
    }
    return true;
}

// Reject flags that have no effect for the given read command, instead of
// silently ignoring them, so misuse is caught rather than producing surprising
// output. Only called for non-write commands; write has its own validation.
bool validate_read_flag_applicability(const ParsedArgs& p, std::ostream& err) {
    const std::string& c = p.command;
    const bool is_row = (c == "head" || c == "cat" || c == "sample");
    const bool scoped =
        is_row || c == "schema" || c == "stats" || c == "count";

    if (!p.output.empty()) {
        err << "Error: -o/--output is only valid for write\n";
        return false;
    }
    if (!p.columns.empty()) {
        err << "Error: --columns is only valid for write\n";
        return false;
    }
    if (p.header_match) {
        err << "Error: --header-match is only valid for write\n";
        return false;
    }
    if (p.verbose) {
        err << "Error: -v/--verbose is only valid for write\n";
        return false;
    }
    if (!is_row && p.limit != -1) {
        err << "Error: -n/--limit is only valid for head/cat/sample\n";
        return false;
    }
    if (!is_row && p.offset != 0) {
        err << "Error: --offset is only valid for head/cat\n";
        return false;
    }
    if (!is_row && (p.has_start || p.has_end)) {
        err << "Error: --start/--end are only valid for head/cat/sample\n";
        return false;
    }
    if (p.has_tag_filter && !is_row) {
        err << "Error: tag filter flags are only valid for head/cat/sample\n";
        return false;
    }
    if (p.has_tag_filter && p.model == "tree") {
        err << "Error: tag filter flags are only valid for table model\n";
        return false;
    }
    if (p.has_tag_filter && !p.device.empty()) {
        err << "Error: tag filter flags cannot be combined with -d/--device\n";
        return false;
    }
    if (!scoped && !p.device.empty()) {
        err << "Error: -d/--device is not valid for " << c << "\n";
        return false;
    }
    if (!scoped && !p.table.empty()) {
        err << "Error: -t/--table is not valid for " << c << "\n";
        return false;
    }
    if (!scoped && !p.measurements.empty()) {
        err << "Error: -m/--measurements is not valid for " << c << "\n";
        return false;
    }
    return true;
}

}  // namespace

int run_cli(const std::vector<std::string>& args, std::ostream& out,
            std::ostream& err) {
    ParsedArgs p = parse_args(args);

    if (p.version) {
        out << "tsfile-cli (Apache TsFile C++) " << TSFILE_CLI_VERSION << "\n";
        return kExitOk;
    }
    if (args.empty()) {
        print_usage(err);
        return kExitUsage;
    }
    if (p.command == "help" || p.command == "--help" || p.command == "-h" ||
        p.help) {
        print_usage(out);
        return kExitOk;
    }
    if (!p.error.empty()) {
        err << "Error: " << p.error << "\n";
        print_usage(err);
        return kExitUsage;
    }
    if (!is_known_command(p.command)) {
        err << "Unknown command: " << p.command << "\n";
        print_usage(err);
        return kExitUsage;
    }
    if (p.command != "write" && p.file.empty()) {
        err << "Error: missing <file.tsfile> argument\n";
        return kExitUsage;
    }
    if (!validate_command_flags(p, err)) {
        print_usage(err);
        return kExitUsage;
    }

    if (p.command == "write") {
        if (!validate_write_flags(p, err)) {
            print_usage(err);
            return kExitUsage;
        }
        storage::libtsfile_init();
        return cmd_write(p, out, err);
    }

    if (!validate_read_flag_applicability(p, err)) {
        print_usage(err);
        return kExitUsage;
    }

    storage::libtsfile_init();
    storage::TsFileReader reader;
    int open_ret = reader.open(p.file);
    if (open_ret != 0) {
        err << "Error: cannot open " << p.file << ": "
            << error_code_message(open_ret) << " (code " << open_ret << ")\n";
        return kExitFile;
    }

    // head/cat/sample/schema dispatch on the data model and would silently
    // ignore the scope flag of the other model; reject that instead.
    if (p.command == "head" || p.command == "cat" || p.command == "sample" ||
        p.command == "schema") {
        const bool table_model = is_table_model(p, reader);
        if (table_model && !p.device.empty()) {
            err << "Error: -d/--device does not apply to the table model; "
                   "use -t/--table (or force --model tree)\n";
            reader.close();
            return kExitUsage;
        }
        if (!table_model && !p.table.empty()) {
            err << "Error: -t/--table does not apply to the tree model; "
                   "use -d/--device (or force --model table)\n";
            reader.close();
            return kExitUsage;
        }
    }

    bool stdout_tty = TSFILE_ISATTY(TSFILE_FILENO(stdout)) != 0;
    OutputFormat fmt = resolve_format(p.format, stdout_tty);

    int code;
    if (p.command == "ls") {
        code = cmd_ls(p, reader, fmt, out, err);
    } else if (p.command == "schema") {
        code = cmd_schema(p, reader, fmt, out, err);
    } else if (p.command == "meta") {
        code = cmd_meta(p, reader, fmt, out, err);
    } else if (p.command == "stats") {
        code = cmd_stats(p, reader, fmt, out, err);
    } else if (p.command == "head") {
        code = cmd_head(p, reader, fmt, out, err);
    } else if (p.command == "cat") {
        code = cmd_cat(p, reader, fmt, out, err);
    } else if (p.command == "count") {
        code = cmd_count(p, reader, fmt, out, err);
    } else if (p.command == "sample") {
        code = cmd_sample(p, reader, fmt, out, err);
    } else {
        err << "Unknown command: " << p.command << "\n";
        code = kExitUsage;
    }

    reader.close();
    return code;
}

}  // namespace tsfile_cli
