// Copyright 2020 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 <lib/zx/stream.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>

#include <sstream>

#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/pointer.h>
#include <src/lib/diagnostics/accessor2logger/log_message.h>
#include <src/lib/fsl/vmo/strings.h>

using fuchsia::diagnostics::FormattedContent;
using fuchsia::logger::LogMessage;

namespace diagnostics::accessor2logger {

namespace {
const char kPidLabel[] = "pid";
const char kTidLabel[] = "tid";
const char kTagLabel[] = "tag";
const char kFileLabel[] = "file";
const char kLineLabel[] = "line";
const char kTagsLabel[] = "tags";
const char kMessageLabel[] = "message";

inline int32_t StringToSeverity(const std::string& input) {
  if (strcasecmp(input.c_str(), "trace") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::TRACE);
  } else if (strcasecmp(input.c_str(), "debug") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::DEBUG);
  } else if (strcasecmp(input.c_str(), "info") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::INFO);
  } else if (strcasecmp(input.c_str(), "warn") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::WARN);
  } else if (strcasecmp(input.c_str(), "error") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::ERROR);
  } else if (strcasecmp(input.c_str(), "fatal") == 0) {
    return static_cast<int32_t>(fuchsia::logger::LogLevelFilter::FATAL);
  }

  return fuchsia::logger::LOG_LEVEL_DEFAULT;
}

inline fit::result<LogMessage, std::string> JsonToLogMessage(rapidjson::Value& value) {
  LogMessage ret = {};
  std::stringstream kv_mapping;

  if (!value.IsObject()) {
    return fit::error("Value is not an object");
  }

  auto metadata = value.FindMember("metadata");
  auto payload = value.FindMember("payload");

  if (metadata == value.MemberEnd() || payload == value.MemberEnd() ||
      !metadata->value.IsObject() || !payload->value.IsObject()) {
    return fit::error("Expected metadata and payload objects");
  }

  auto timestamp = metadata->value.FindMember("timestamp");
  if (timestamp == metadata->value.MemberEnd() || !timestamp->value.IsUint64()) {
    return fit::error("Expected metadata.timestamp key");
  }
  ret.time = timestamp->value.GetUint64();

  auto severity = metadata->value.FindMember("severity");
  if (severity == metadata->value.MemberEnd() || !severity->value.IsString()) {
    return fit::error("Expected metadata.severity key");
  }
  ret.severity = StringToSeverity(severity->value.GetString());

  auto moniker = value.FindMember("moniker");
  std::string moniker_string;
  if (moniker != value.MemberEnd() && moniker->value.IsString()) {
    moniker_string = std::move(moniker->value.GetString());
  }

  uint32_t dropped_logs = 0;
  if (metadata->value.HasMember("errors")) {
    auto& errors = metadata->value["errors"];
    if (errors.IsArray()) {
      for (rapidjson::SizeType i = 0; i < errors.Size(); i++) {
        auto* val = rapidjson::Pointer("/dropped_logs/count").Get(errors[i]);
        if (val && val->IsUint()) {
          dropped_logs += val->GetUint();
        }
      }
    }
  }

  // Flatten payloads containing a "root" node.
  // TODO(fxbug.dev/63409): Remove this when "root" is omitted from logs.
  if (payload->value.MemberCount() == 1 && payload->value.HasMember("root")) {
    payload = payload->value.FindMember("root");
    if (!payload->value.IsObject()) {
      return fit::error("Expected payload.root to be an object if present");
    }
  }
  std::string msg;
  std::string filename;
  std::optional<int> line_number;
  for (auto it = payload->value.MemberBegin(); it != payload->value.MemberEnd(); ++it) {
    if (!it->name.IsString()) {
      return fit::error("A key is not a string");
    }
    std::string name = it->name.GetString();
    if (name == kMessageLabel && it->value.IsString()) {
      msg = std::move(it->value.GetString());
    } else if (name == kTagLabel) {
      // TODO(fxbug.dev/63007): Parse only "tags"
      if (!it->value.IsString()) {
        return fit::error("Tag field must contain a single string value");
      }
      ret.tags.emplace_back(std::move(it->value.GetString()));
    } else if (name == kTagsLabel) {
      if (it->value.IsString()) {
        ret.tags.emplace_back(std::move(it->value.GetString()));
      } else if (it->value.IsArray()) {
        for (rapidjson::SizeType i = 0; i < it->value.Size(); ++i) {
          auto& val = it->value[i];
          if (!val.IsString()) {
            return fit::error("Tags array must contain strings");
          }
          ret.tags.emplace_back(std::move(val.GetString()));
        }
      } else {
        return fit::error("Tags must be a string or array of strings");
      }
    } else if (name == kTidLabel && it->value.IsUint64()) {
      ret.tid = it->value.GetUint64();
    } else if (name == kPidLabel && it->value.IsUint64()) {
      ret.pid = it->value.GetUint64();
    } else if (name == kFileLabel && it->value.IsString()) {
      filename = it->value.GetString();
    } else if (name == kLineLabel && it->value.IsUint64()) {
      line_number = it->value.GetUint64();
    } else {
      // If the name of the field is not a known special field, treat it as a key/value pair and
      // append to the message.
      kv_mapping << " " << std::move(name) << "=";
      if (it->value.IsInt64()) {
        kv_mapping << it->value.GetInt64();
      } else if (it->value.IsUint64()) {
        kv_mapping << it->value.GetUint64();
      } else if (it->value.IsDouble()) {
        kv_mapping << it->value.GetDouble();
      } else if (it->value.IsString()) {
        kv_mapping << std::move(it->value.GetString());
      } else {
        kv_mapping << "<unknown>";
      }
    }
  }
  if (!filename.empty() && line_number.has_value()) {
    std::stringstream enc;
    enc << "[" << filename << "(" << line_number.value() << ")] ";
    ret.msg = enc.str();
  }
  ret.msg += msg;

  ret.msg += kv_mapping.str();

  // If there are no tags, automatically tag with the component moniker.
  if (ret.tags.size() == 0 && !moniker_string.empty()) {
    ret.tags.emplace_back(std::move(moniker_string));
  }

  if (dropped_logs > 0) {
    ret.dropped_logs = dropped_logs;
  }

  return fit::ok(std::move(ret));
}
}  // namespace

fit::result<std::vector<fit::result<fuchsia::logger::LogMessage, std::string>>, std::string>
ConvertFormattedContentToLogMessages(FormattedContent content) {
  std::vector<fit::result<LogMessage, std::string>> output;

  if (!content.is_json()) {
    // Expecting JSON in all cases.
    return fit::error("Expected json content");
  }

  std::string data;
  if (!fsl::StringFromVmo(content.json(), &data)) {
    return fit::error("Failed to read string from VMO");
  }
  content.json().vmo.reset();

  rapidjson::Document d;
  d.Parse(std::move(data));
  if (d.HasParseError()) {
    std::string error = "Failed to parse content as JSON. Offset " +
                        std::to_string(d.GetErrorOffset()) + ": " +
                        rapidjson::GetParseError_En(d.GetParseError());
    return fit::error(std::move(error));
  }

  if (!d.IsArray()) {
    return fit::error("Expected content to contain an array");
  }

  for (rapidjson::SizeType i = 0; i < d.Size(); ++i) {
    output.emplace_back(JsonToLogMessage(d[i]));
  }

  return fit::ok(std::move(output));
}

}  // namespace diagnostics::accessor2logger
