// Copyright 2019 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 "src/developer/forensics/feedback_data/config.h"

#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>

#include "src/lib/files/file.h"
#include "third_party/rapidjson/include/rapidjson/document.h"
#include "third_party/rapidjson/include/rapidjson/error/en.h"
#include "third_party/rapidjson/include/rapidjson/schema.h"
#include "third_party/rapidjson/include/rapidjson/stringbuffer.h"

namespace forensics {
namespace feedback_data {
namespace {

const char kSchema[] = R"({
  "type": "object",
  "properties": {
    "annotation_allowlist": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "uniqueItems": true
    },
    "attachment_allowlist": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "uniqueItems": true
    }
  },
  "required": [
    "annotation_allowlist",
    "attachment_allowlist"
  ],
  "additionalProperties": false
})";

const char kAnnotationWhitelistKey[] = "annotation_allowlist";
const char kAttachmentWhitelistKey[] = "attachment_allowlist";

bool CheckAgainstSchema(rapidjson::Document& doc) {
  // Check that the schema is actually valid.
  rapidjson::Document sd;
  rapidjson::ParseResult ok = sd.Parse(kSchema);
  if (!ok) {
    FX_LOGS(ERROR) << "invalid JSON schema for config at offset " << ok.Offset() << " "
                   << rapidjson::GetParseError_En(ok.Code());
    return false;
  }

  // Check the document against the schema.
  rapidjson::SchemaDocument schema(sd);
  rapidjson::SchemaValidator validator(schema);
  if (!doc.Accept(validator)) {
    rapidjson::StringBuffer sb;
    validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
    FX_LOGS(ERROR) << "config does not match schema, violating '"
                   << validator.GetInvalidSchemaKeyword() << "' rule";
    return false;
  }
  return true;
}

}  // namespace

zx_status_t ParseConfig(const std::string& filepath, Config* config) {
  std::string json;
  if (!files::ReadFileToString(filepath, &json)) {
    FX_LOGS(ERROR) << "error reading config file at " << filepath;
    return ZX_ERR_IO;
  }

  rapidjson::Document doc;
  rapidjson::ParseResult ok = doc.Parse(json.c_str());
  if (!ok) {
    FX_LOGS(ERROR) << "error parsing config as JSON at offset " << ok.Offset() << " "
                   << rapidjson::GetParseError_En(ok.Code());
    return ZX_ERR_INTERNAL;
  }

  if (!CheckAgainstSchema(doc)) {
    return ZX_ERR_INTERNAL;
  }

  // We use a local config to only set the out argument after all the checks.
  Config local_config = {};
  // It is safe to directly access the field as the keys are marked as required and we have checked
  // the config against the schema.
  for (const auto& annotation_key : doc[kAnnotationWhitelistKey].GetArray()) {
    // No need to warn on duplicates as the schema enforces "uniqueItems".
    local_config.annotation_allowlist.insert(annotation_key.GetString());
  }
  for (const auto& attachment_key : doc[kAttachmentWhitelistKey].GetArray()) {
    // No need to warn on duplicates as the schema enforces "uniqueItems".
    local_config.attachment_allowlist.insert(attachment_key.GetString());
  }

  *config = local_config;
  return ZX_OK;
}

}  // namespace feedback_data
}  // namespace forensics
