/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed 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 "flatbuffers/flatc.h"

#include <list>

#define FLATC_VERSION "1.9.0 (" __DATE__ " " __TIME__ ")"

namespace flatbuffers {

void FlatCompiler::ParseFile(
    flatbuffers::Parser &parser, const std::string &filename,
    const std::string &contents,
    std::vector<const char *> &include_directories) const {
  auto local_include_directory = flatbuffers::StripFileName(filename);
  include_directories.push_back(local_include_directory.c_str());
  include_directories.push_back(nullptr);
  if (!parser.Parse(contents.c_str(), &include_directories[0],
                    filename.c_str()))
    Error(parser.error_, false, false);
  include_directories.pop_back();
  include_directories.pop_back();
}

void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const {
  params_.warn_fn(this, warn, show_exe_name);
}

void FlatCompiler::Error(const std::string &err, bool usage,
                         bool show_exe_name) const {
  params_.error_fn(this, err, usage, show_exe_name);
}

std::string FlatCompiler::GetUsageString(const char *program_name) const {
  std::stringstream ss;
  ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
  for (size_t i = 0; i < params_.num_generators; ++i) {
    const Generator &g = params_.generators[i];

    std::stringstream full_name;
    full_name << std::setw(12) << std::left << g.generator_opt_long;
    const char *name = g.generator_opt_short ? g.generator_opt_short : "  ";
    const char *help = g.generator_help;

    ss << "  " << full_name.str() << " " << name << "    " << help << ".\n";
  }
  // clang-format off
  ss <<
    "  -o PATH            Prefix PATH to all generated files.\n"
    "  -I PATH            Search for includes in the specified path.\n"
    "  -M                 Print make rules for generated files.\n"
    "  --version          Print the version number of flatc and exit.\n"
    "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
    "                     no trailing commas in tables/vectors.\n"
    "  --allow-non-utf8   Pass non-UTF-8 input through parser and emit nonstandard\n"
    "                     \\x escapes in JSON. (Default is to raise parse error on\n"
    "                     non-UTF-8 input.)\n"
    "  --defaults-json    Output fields whose value is the default when\n"
    "                     writing JSON\n"
    "  --unknown-json     Allow fields in JSON that are not defined in the\n"
    "                     schema. These fields will be discared when generating\n"
    "                     binaries.\n"
    "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
    "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
    "                     also implies --no-prefix.\n"
    "  --gen-includes     (deprecated), this is the default behavior.\n"
    "                     If the original behavior is required (no include\n"
    "                     statements) use --no-includes.\n"
    "  --no-includes      Don\'t generate include statements for included\n"
    "                     schemas the generated file depends on (C++).\n"
    "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
    "  --gen-onefile      Generate single output file for C# and Go.\n"
    "  --gen-name-strings Generate type name functions for C++.\n"
    "  --gen-object-api   Generate an additional object-based API.\n"
    "  --cpp-ptr-type T   Set object API pointer type (default std::unique_ptr)\n"
    "  --cpp-str-type T   Set object API string type (default std::string)\n"
    "                     T::c_str() and T::length() must be supported\n"
    "  --gen-nullable     Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
    "  --object-prefix    Customise class prefix for C++ object-based API.\n"
    "  --object-suffix    Customise class suffix for C++ object-based API.\n"
    "                     Default value is \"T\"\n"
    "  --no-js-exports    Removes Node.js style export lines in JS.\n"
    "  --goog-js-export   Uses goog.exports* for closure compiler exporting in JS.\n"
    "  --go-namespace     Generate the overrided namespace in Golang.\n"
    "  --go-import        Generate the overrided import for flatbuffers in Golang.\n"
    "                     (default is \"github.com/google/flatbuffers/go\")\n"
    "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
    "                     This may crash flatc given a mismatched schema.\n"
    "  --size-prefixed    Input binaries are size prefixed buffers.\n"
    "  --proto            Input is a .proto, translate to .fbs.\n"
    "  --oneof-union      Translate .proto oneofs to flatbuffer unions.\n"
    "  --grpc             Generate GRPC interfaces for the specified languages\n"
    "  --schema           Serialize schemas instead of JSON (use with -b)\n"
    "  --bfbs-comments    Add doc comments to the binary schema files.\n"
    "  --conform FILE     Specify a schema the following schemas should be\n"
    "                     an evolution of. Gives errors if not.\n"
    "  --conform-includes Include path for the schema given with --conform\n"
    "    PATH             \n"
    "  --include-prefix   Prefix this path to any generated include statements.\n"
    "    PATH\n"
    "  --keep-prefix      Keep original prefix of schema include statement.\n"
    "  --no-fb-import     Don't include flatbuffers import statement for TypeScript.\n"
    "  --no-ts-reexport   Don't re-export imported dependencies for TypeScript.\n"
    "  --reflect-types    Add minimal type reflection to code generation.\n"
    "  --reflect-names    Add minimal type/name reflection.\n"
    "FILEs may be schemas (must end in .fbs), or JSON files (conforming to preceding\n"
    "schema). FILEs after the -- must be binary flatbuffer format files.\n"
    "Output files are named using the base file name of the input,\n"
    "and written to the current directory or the path given by -o.\n"
    "example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
  // clang-format on
  return ss.str();
}

int FlatCompiler::Compile(int argc, const char **argv) {
  if (params_.generators == nullptr || params_.num_generators == 0) {
    return 0;
  }

  flatbuffers::IDLOptions opts;
  std::string output_path;

  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  bool grpc_enabled = false;
  std::vector<std::string> filenames;
  std::list<std::string> include_directories_storage;
  std::vector<const char *> include_directories;
  std::vector<const char *> conform_include_directories;
  std::vector<bool> generator_enabled(params_.num_generators, false);
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  std::string conform_to_schema;

  for (int argi = 0; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--conform") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        conform_to_schema = flatbuffers::PosixPath(argv[argi]);
      } else if (arg == "--conform-includes") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        conform_include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--include-prefix") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        opts.include_prefix = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "--keep-prefix") {
        opts.keep_include_path = true;
      } else if (arg == "--strict-json") {
        opts.strict_json = true;
      } else if (arg == "--allow-non-utf8") {
        opts.allow_non_utf8 = true;
      } else if (arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if (arg == "--goog-js-export") {
        opts.use_goog_js_export_format = true;
      } else if (arg == "--go-namespace") {
        if (++argi >= argc) Error("missing golang namespace" + arg, true);
        opts.go_namespace = argv[argi];
      } else if (arg == "--go-import") {
        if (++argi >= argc) Error("missing golang import" + arg, true);
        opts.go_import = argv[argi];
      } else if (arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if (arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if (arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if (arg == "--no-union-value-namespacing") {
        opts.union_value_namespacing = false;
      } else if (arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if (arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if (arg == "--gen-object-api") {
        opts.generate_object_based_api = true;
      } else if (arg == "--cpp-ptr-type") {
        if (++argi >= argc) Error("missing type following" + arg, true);
        opts.cpp_object_api_pointer_type = argv[argi];
      } else if (arg == "--cpp-str-type") {
        if (++argi >= argc) Error("missing type following" + arg, true);
        opts.cpp_object_api_string_type = argv[argi];
      } else if (arg == "--gen-nullable") {
        opts.gen_nullable = true;
      } else if (arg == "--object-prefix") {
        if (++argi >= argc) Error("missing prefix following" + arg, true);
        opts.object_prefix = argv[argi];
      } else if (arg == "--object-suffix") {
        if (++argi >= argc) Error("missing suffix following" + arg, true);
        opts.object_suffix = argv[argi];
      } else if (arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if (arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if (arg == "--size-prefixed") {
        opts.size_prefixed = true;
      } else if (arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if (arg == "--proto") {
        opts.proto_mode = true;
      } else if (arg == "--oneof-union") {
        opts.proto_oneof_union = true;
      } else if (arg == "--schema") {
        schema_binary = true;
      } else if (arg == "-M") {
        print_make_rules = true;
      } else if (arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION);
        exit(0);
      } else if (arg == "--grpc") {
        grpc_enabled = true;
      } else if (arg == "--bfbs-comments") {
        opts.binary_schema_comments = true;
      } else if (arg == "--no-fb-import") {
        opts.skip_flatbuffers_import = true;
      } else if (arg == "--no-ts-reexport") {
        opts.reexport_ts_modules = false;
      } else if (arg == "--reflect-types") {
        opts.mini_reflect = IDLOptions::kTypes;
      } else if (arg == "--reflect-names") {
        opts.mini_reflect = IDLOptions::kTypesAndNames;
      } else {
        for (size_t i = 0; i < params_.num_generators; ++i) {
          if (arg == params_.generators[i].generator_opt_long ||
              (params_.generators[i].generator_opt_short &&
               arg == params_.generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            opts.lang_to_generate |= params_.generators[i].lang;
            goto found;
          }
        }
        Error("unknown commandline argument: " + arg, true);
      found:;
      }
    } else {
      filenames.push_back(flatbuffers::PosixPath(argv[argi]));
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator && conform_to_schema.empty()) {
    Error("no options: specify at least one generator.", true);
  }

  flatbuffers::Parser conform_parser;
  if (!conform_to_schema.empty()) {
    std::string contents;
    if (!flatbuffers::LoadFile(conform_to_schema.c_str(), true, &contents))
      Error("unable to load schema: " + conform_to_schema);
    ParseFile(conform_parser, conform_to_schema, contents,
              conform_include_directories);
  }

  std::unique_ptr<flatbuffers::Parser> parser(new flatbuffers::Parser(opts));

  for (auto file_it = filenames.begin(); file_it != filenames.end();
       ++file_it) {
    auto &filename = *file_it;
    std::string contents;
    if (!flatbuffers::LoadFile(filename.c_str(), true, &contents))
      Error("unable to load file: " + filename);

    bool is_binary =
        static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
    auto ext = flatbuffers::GetExtension(filename);
    auto is_schema = ext == "fbs" || ext == "proto";
    if (is_binary) {
      parser->builder_.Clear();
      parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
      if (!raw_binary) {
        // Generally reading binaries that do not correspond to the schema
        // will crash, and sadly there's no way around that when the binary
        // does not contain a file identifier.
        // We'd expect that typically any binary used as a file would have
        // such an identifier, so by default we require them to match.
        if (!parser->file_identifier_.length()) {
          Error("current schema has no file_identifier: cannot test if \"" +
                filename +
                "\" matches the schema, use --raw-binary to read this file"
                " anyway.");
        } else if (!flatbuffers::BufferHasIdentifier(
                       contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) {
          Error("binary \"" + filename +
                "\" does not have expected file_identifier \"" +
                parser->file_identifier_ +
                "\", use --raw-binary to read this file anyway.");
        }
      }
    } else {
      // Check if file contains 0 bytes.
      if (contents.length() != strlen(contents.c_str())) {
        Error("input file appears to be binary: " + filename, true);
      }
      if (is_schema) {
        // If we're processing multiple schemas, make sure to start each
        // one from scratch. If it depends on previous schemas it must do
        // so explicitly using an include.
        parser.reset(new flatbuffers::Parser(opts));
      }
      ParseFile(*parser.get(), filename, contents, include_directories);
      if (!is_schema && !parser->builder_.GetSize()) {
        // If a file doesn't end in .fbs, it must be json/binary. Ensure we
        // didn't just parse a schema with a different extension.
        Error(
            "input file is neither json nor a .fbs (schema) file: " + filename,
            true);
      }
      if (is_schema && !conform_to_schema.empty()) {
        auto err = parser->ConformTo(conform_parser);
        if (!err.empty()) Error("schemas don\'t conform: " + err);
      }
      if (schema_binary) {
        parser->Serialize();
        parser->file_extension_ = reflection::SchemaExtension();
      }
    }

    std::string filebase =
        flatbuffers::StripPath(flatbuffers::StripExtension(filename));

    for (size_t i = 0; i < params_.num_generators; ++i) {
      parser->opts.lang = params_.generators[i].lang;
      if (generator_enabled[i]) {
        if (!print_make_rules) {
          flatbuffers::EnsureDirExists(output_path);
          if ((!params_.generators[i].schema_only || is_schema) &&
              !params_.generators[i].generate(*parser.get(), output_path,
                                              filebase)) {
            Error(std::string("Unable to generate ") +
                  params_.generators[i].lang_name + " for " + filebase);
          }
        } else {
          std::string make_rule = params_.generators[i].make_rule(
              *parser.get(), output_path, filename);
          if (!make_rule.empty())
            printf("%s\n",
                   flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
        }
        if (grpc_enabled) {
          if (params_.generators[i].generateGRPC != nullptr) {
            if (!params_.generators[i].generateGRPC(*parser.get(), output_path,
                                                    filebase)) {
              Error(std::string("Unable to generate GRPC interface for") +
                    params_.generators[i].lang_name);
            }
          } else {
            Warn(std::string("GRPC interface generator not implemented for ") +
                 params_.generators[i].lang_name);
          }
        }
      }
    }

    if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase);

    // We do not want to generate code for the definitions in this file
    // in any files coming up next.
    parser->MarkGenerated();
  }
  return 0;
}

}  // namespace flatbuffers
