// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <libgen.h>

#include <fstream>
#include <map>
#include <regex>
#include <string>

#include <rapidjson/document.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>
#include <src/lib/fxl/command_line.h>

using namespace rapidjson;

static constexpr char kArgAllowComments[] = "allow_comments";

static constexpr char kUsage[] = R"(
Usage: %s [--allow_comments] <schema> <file> [stamp]

Arguments:
  --allow_comments: Parses and ignores /* */ and // comments in the input file.
    This does not apply to the schema file.
)";

// Reads the content of a file into a JSON document.
//
// The template parameter |parse_flags| is passed to the RapidJSON Parse method and controls
// the JSON parsing behavior. This can be used to enable parsing non-standard JSON syntax,
// like comments.
template <unsigned parse_flags = kParseDefaultFlags>
bool ReadDocument(std::string file, Document* document) {
  std::ifstream file_stream(file);
  if (!file_stream.is_open()) {
    fprintf(stderr, "Error: unable to open file %s.\n", file.c_str());
    return false;
  }
  std::string content((std::istreambuf_iterator<char>(file_stream)),
                      std::istreambuf_iterator<char>());
  file_stream.close();
  if (document->Parse<parse_flags>(content).HasParseError()) {
    fprintf(stderr, "Error: unable to parse JSON in file %s.\n", file.c_str());
    return false;
  }
  return true;
}

// A schema provider that can find schemas specified as URIs/paths relative to
// the main schema.
class LocalSchemaProvider : public IRemoteSchemaDocumentProvider {
 public:
  explicit LocalSchemaProvider(const std::string directory)
      : directory_(directory), has_errors_(false) {}
  ~LocalSchemaProvider() override {}

  const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) override {
    std::string input(uri, length);
    std::smatch matches;
    std::regex pattern("^(file:)?([^/#:]+)$");
    if (!std::regex_search(input, matches, pattern)) {
      fprintf(stderr, "Error: could not find schema %s.\n", input.c_str());
      has_errors_ = true;
      return nullptr;
    }
    std::string file_name = matches[matches.size() == 2 ? 1 : 2].str();
    if (documents_[file_name]) {
      return documents_[file_name].get();
    }
    Document schema_document;
    std::string file_path = directory_ + "/" + file_name;
    if (!ReadDocument(file_path, &schema_document)) {
      // ReadDocument already prints a useful error message.
      has_errors_ = true;
      return nullptr;
    }
    documents_[file_name] = std::make_unique<SchemaDocument>(schema_document);
    return documents_[file_name].get();
  }

  // Returns true if some schemas could not be resolved.
  // By default, missing schemas are just ignored.
  bool HasErrors() { return has_errors_; }

 private:
  // Map of resolved documents.
  std::map<std::string, std::unique_ptr<SchemaDocument>> documents_;
  // Base directory for schema paths.
  const std::string directory_;
  // Whether some schema references could not be resolved.
  bool has_errors_;
};

// Returns the base directory of a given file.
std::string BaseDir(const std::string file) {
  char* file_copy = strdup(file.c_str());
  char* base = dirname(file_copy);
  std::string result(base);
  free(file_copy);
  return result;
}

int main(int argc, const char** argv) {
  const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  const auto& positional_args = command_line.positional_args();

  if (positional_args.size() < 2 || positional_args.size() > 3) {
    printf(kUsage, argv[0]);
    return 1;
  }

  const std::string schema_path = positional_args[0];
  const std::string file_path = positional_args[1];
  const bool allow_comments = command_line.HasOption(kArgAllowComments);

  Document schema_document;
  if (!ReadDocument(schema_path, &schema_document)) {
    return 1;
  }

  Document file_document;
  bool file_read_ok = allow_comments ? ReadDocument<kParseCommentsFlag>(file_path, &file_document)
                                     : ReadDocument(file_path, &file_document);
  if (!file_read_ok) {
    return 1;
  }

  std::string schema_base = BaseDir(schema_path);
  LocalSchemaProvider provider(schema_base);
  SchemaDocument schema(schema_document, nullptr /* uri */, 0 /* uriLength */, &provider);
  SchemaValidator validator(schema);
  if (!file_document.Accept(validator)) {
    fprintf(stderr, "Error: the file %s is invalid according to schema %s.\n", file_path.c_str(),
            schema_path.c_str());
    StringBuffer buffer;
    validator.GetInvalidSchemaPointer().StringifyUriFragment(buffer);
    fprintf(stderr, " - location in schema     %s\n", buffer.GetString());
    fprintf(stderr, " - affected keyword       %s\n", validator.GetInvalidSchemaKeyword());
    buffer.Clear();
    validator.GetInvalidDocumentPointer().StringifyUriFragment(buffer);
    fprintf(stderr, " - document reference     %s\n", buffer.GetString());
    return 1;
  }
  if (provider.HasErrors()) {
    return 1;
  }

  if (positional_args.size() == 3) {
    // Write the stamp file if one was given.
    std::string stamp_path = positional_args[2];
    std::ofstream stamp(stamp_path);
    stamp.close();
  }

  return 0;
}
