// Copyright 2017 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 "garnet/bin/network_time/time_server_config.h"

#include <string>
#include <vector>

#include <fstream>
#include <sstream>

#include <protocol.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>

#include "lib/syslog/cpp/logger.h"

#define MULTILINE(...) #__VA_ARGS__

namespace time_server {

const char* config_schema = MULTILINE({
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "properties" : {
    "servers" : {
      "items" : {
        "properties" : {
          "addresses" : {
            "items" : {
              "properties" : {"address" : {"type" : "string"}},
              "required" : ["address"],
              "type" : "object"
            },
            "minItems" : 1,
            "type" : "array"
          },
          "name" : {"type" : "string"},
          "publicKey" : {"maxLength" : 64, "minLength" : 64, "type" : "string"}
        },
        "required" : [ "publicKey", "addresses", "name" ],
        "type" : "object"
      },
      "minItems" : 1,
      "type" : "array"
    }
  },
  "required" : ["servers"],
  "type" : "object"
});

static bool readFile(std::string* out_contents, const char* filename) {
  std::ifstream serverFile;
  serverFile.open(filename);
  if ((serverFile.rdstate() & std::ifstream::failbit) != 0) {
    FX_LOGS(ERROR) << "Opening " << filename << ": " << strerror(errno);
    return false;
  }
  std::stringstream strStream;
  strStream << serverFile.rdbuf();
  out_contents->assign(strStream.str());
  return true;
}

std::vector<RoughTimeServer> TimeServerConfig::ServerList() {
  return server_list_;
}

bool checkSchema(rapidjson::Document& d) {
  rapidjson::Document sd;
  if (sd.Parse(config_schema).HasParseError()) {
    FX_LOGS(ERROR) << "Schema not valid";
    return false;
  }
  rapidjson::SchemaDocument schema(sd);
  rapidjson::SchemaValidator validator(schema);
  if (!d.Accept(validator)) {
    // Input JSON is invalid according to the schema
    // Output diagnostic information
    rapidjson::StringBuffer sb;
    validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
    FX_LOGS(ERROR) << "Invalid schema: " << sb.GetString();
    FX_LOGS(ERROR) << "Invalid keyword: "
                   << validator.GetInvalidSchemaKeyword();
    sb.Clear();
    validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
    FX_LOGS(ERROR) << "Invalid document: " << sb.GetString();
    return false;
  }
  return true;
}

bool TimeServerConfig::Parse(std::string config_file) {
  std::string json;
  if (!readFile(&json, config_file.c_str())) {
    return false;
  }

  rapidjson::Document doc;
  rapidjson::ParseResult ok = doc.Parse(json.c_str());
  if (!ok) {
    FX_LOGS(ERROR) << "JSON parse error: "
                   << rapidjson::GetParseError_En(ok.Code()) << "("
                   << ok.Offset() << ")";
    return false;
  }
  if (!checkSchema(doc)) {
    return false;
  }

  const rapidjson::Value& servers = doc["servers"];
  for (rapidjson::SizeType i = 0; i < servers.Size(); i++) {
    const rapidjson::Value& server = servers[i];

    const rapidjson::Value& addresses = server["addresses"];
    std::string name = server["name"].GetString();
    std::string public_key_str = server["publicKey"].GetString();
    for (rapidjson::SizeType j = 0; j < addresses.Size(); j++) {
      const rapidjson::Value& address = addresses[j];

      std::string address_str = address["address"].GetString();
      uint8_t public_key[roughtime::kPublicKeyLength];
      if (public_key_str.length() != roughtime::kPublicKeyLength * 2) {
        FX_LOGS(ERROR) << "Invalid public key: " << public_key_str;
        return false;
      }
      for (unsigned int k = 0; k < roughtime::kPublicKeyLength; k++) {
        char hex[3] = {0};
        hex[0] = public_key_str.at(k * 2);
        hex[1] = public_key_str.at(k * 2 + 1);
        public_key[k] = strtoul(hex, NULL, 16);
      }

      RoughTimeServer server(std::move(name), std::move(address_str),
                             public_key, roughtime::kPublicKeyLength);
      server_list_.push_back(server);
    }
  }
  return true;
}

}  // namespace time_server
