/*
 * 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.7.0 (" __DATE__ ")"

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";
  }
  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#.\n"
      "  --gen-name-strings Generate type name functions for C++.\n"
      "  --escape-proto-ids Disable appending '_' in namespaces names.\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"
      "  --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"
      "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
      "                     This may crash flatc given a mismatched schema.\n"
      "  --proto            Input is a .proto, translate to .fbs.\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"
      "FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
      "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";
  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 == "--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-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 == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
      } else if(arg == "--escape-proto-ids") {
        opts.escape_proto_identifiers = 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 {
        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 is_schema = flatbuffers::GetExtension(filename) == "fbs";
    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())) {
          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 && !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
