// Copyright 2019 The Chromium OS 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 "print_tools/ipp_in_json.h"

#include <memory>
#include <utility>

#include <base/json/json_writer.h>
#include <base/macros.h>
#include <base/values.h>

namespace {

std::unique_ptr<base::DictionaryValue> SaveAsJson(const ipp::Collection* coll);

// It saves a single value (at given index) from the attribute as JSON
// structure. The parameter "attr" cannot be nullptr, "index" must be correct.
std::unique_ptr<base::Value> SaveAsJson(const ipp::Attribute* attr,
                                        unsigned index) {
  CHECK(attr != nullptr);
  CHECK(index < attr->GetSize());
  using AttrType = ipp::AttrType;
  switch (attr->GetType()) {
    case AttrType::integer: {
      int vi;
      attr->GetValue(&vi, index);
      return std::make_unique<base::Value>(vi);
    }
    case AttrType::boolean: {
      int vb;
      attr->GetValue(&vb, index);
      return std::make_unique<base::Value>(static_cast<bool>(vb));
    }
    case AttrType::enum_: {
      std::string vs;
      attr->GetValue(&vs, index);
      if (vs.empty()) {
        int vi;
        attr->GetValue(&vi, index);
        return std::make_unique<base::Value>(vi);
      }
      return std::make_unique<base::Value>(vs);
    }
    case AttrType::collection:
      return SaveAsJson(attr->GetCollection(index));
    case AttrType::text:
    case AttrType::name: {
      ipp::StringWithLanguage vs;
      attr->GetValue(&vs, index);
      if (vs.language.empty())
        return std::make_unique<base::Value>(vs.value);
      std::unique_ptr<base::DictionaryValue> obj(new base::DictionaryValue);
      obj->SetString("value", vs.value);
      obj->SetString("language", vs.language);
      return obj;
    }
    case AttrType::dateTime:
    case AttrType::resolution:
    case AttrType::rangeOfInteger:
    case AttrType::octetString:
    case AttrType::keyword:
    case AttrType::uri:
    case AttrType::uriScheme:
    case AttrType::charset:
    case AttrType::naturalLanguage:
    case AttrType::mimeMediaType: {
      std::string vs;
      attr->GetValue(&vs, index);
      return std::make_unique<base::Value>(vs);
    }
  }
  return std::make_unique<base::Value>();  // not reachable
}

// It saves all attribute's values as JSON structure.
// The parameter "attr" cannot be nullptr.
std::unique_ptr<base::Value> SaveAsJson(const ipp::Attribute* attr) {
  CHECK(attr != nullptr);
  if (attr->IsASet()) {
    auto arr = std::make_unique<base::ListValue>();
    const unsigned size = attr->GetSize();
    for (unsigned i = 0; i < size; ++i)
      arr->Append(SaveAsJson(attr, i));
    return arr;
  } else {
    return SaveAsJson(attr, 0);
  }
}

// It saves a given Collection as JSON object.
// The parameter "coll" cannot be nullptr.
std::unique_ptr<base::DictionaryValue> SaveAsJson(const ipp::Collection* coll) {
  CHECK(coll != nullptr);
  auto obj = std::make_unique<base::DictionaryValue>();
  std::vector<const ipp::Attribute*> attrs = coll->GetAllAttributes();

  for (auto a : attrs) {
    auto state = a->GetState();
    if (state == ipp::AttrState::unset)
      continue;

    if (state == ipp::AttrState::set) {
      auto obj2 = std::make_unique<base::DictionaryValue>();
      obj2->SetString("type", ToString(a->GetType()));
      obj2->Set("value", SaveAsJson(a));
      obj->Set(a->GetName(), std::move(obj2));
    } else {
      obj->SetString(a->GetName(), ToString(state));
    }
  }

  return obj;
}

// It saves all groups from given Package as JSON object.
// The parameter "pkg" cannot be nullptr.
std::unique_ptr<base::DictionaryValue> SaveAsJson(const ipp::Package* pkg) {
  CHECK(pkg != nullptr);
  auto obj = std::make_unique<base::DictionaryValue>();
  std::vector<const ipp::Group*> groups = pkg->GetAllGroups();

  for (auto g : groups) {
    const size_t size = g->GetSize();
    if (size == 0)
      continue;
    if (g->IsASet()) {
      auto arr = std::make_unique<base::ListValue>();
      for (size_t i = 0; i < size; ++i)
        arr->Append(SaveAsJson(g->GetCollection(i)));
      obj->Set(ToString(g->GetName()), std::move(arr));
    } else {
      obj->Set(ToString(g->GetName()), SaveAsJson(g->GetCollection()));
    }
  }

  return obj;
}

// Saves given logs as JSON array.
std::unique_ptr<base::ListValue> SaveAsJson(const std::vector<ipp::Log>& log) {
  auto arr = std::make_unique<base::ListValue>();
  for (const auto& l : log) {
    auto obj = std::make_unique<base::DictionaryValue>();
    obj->SetString("message", l.message);
    if (!l.frame_context.empty())
      obj->SetString("frame_context", l.frame_context);
    if (!l.parser_context.empty())
      obj->SetString("parser_context", l.parser_context);
    arr->Append(std::move(obj));
  }
  return arr;
}

}  // namespace

bool ConvertToJson(const ipp::Response& response,
                   const std::vector<ipp::Log>& log,
                   bool compressed_json,
                   std::string* json) {
  // Build structure.
  auto doc = std::make_unique<base::DictionaryValue>();
  doc->SetString("status", ipp::ToString(response.StatusCode()));
  if (!log.empty()) {
    doc->Set("parsing_logs", SaveAsJson(log));
  }
  doc->Set("response", SaveAsJson(&response));
  // Convert to JSON.
  bool result;
  if (compressed_json) {
    result = base::JSONWriter::Write(*doc, json);
  } else {
    const int options = base::JSONWriter::OPTIONS_PRETTY_PRINT;
    result = base::JSONWriter::WriteWithOptions(*doc, options, json);
  }
  return result;
}
