// 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 "src/modular/lib/fidl/json_xdr.h"

#include <lib/fidl/cpp/string.h>
#include <lib/syslog/cpp/macros.h>

#include <string>

using JsonDoc = rapidjson::Document;
using JsonValue = rapidjson::Value;

namespace modular {

namespace {
const char* JsonTypeName(const rapidjson::Type type) {
  switch (type) {
    case rapidjson::kNullType:
      return "null";
    case rapidjson::kFalseType:
      return "false";
    case rapidjson::kTrueType:
      return "true";
    case rapidjson::kObjectType:
      return "object";
    case rapidjson::kArrayType:
      return "array";
    case rapidjson::kStringType:
      return "string";
    case rapidjson::kNumberType:
      return "number";
  };
}
}  // namespace

// HACK(mesch): We should not need this, get rid of it.
thread_local JsonValue XdrContext::null_ = JsonValue();

XdrContext::XdrContext(const XdrOp op, JsonDoc* const doc, std::string* const error)
    : parent_(nullptr), name_(nullptr), error_(error), op_(op), doc_(doc), value_(doc) {
  FX_DCHECK(doc_ != nullptr);
  FX_DCHECK(error_ != nullptr);
}

XdrContext::XdrContext(XdrContext* const parent, const char* const name, const XdrOp op,
                       JsonDoc* const doc, JsonValue* const value)
    : parent_(parent), name_(name), error_(nullptr), op_(op), doc_(doc), value_(value) {
  FX_DCHECK(parent_ != nullptr);
  FX_DCHECK(doc_ != nullptr);
  FX_DCHECK(value_ != nullptr);
}

XdrContext::~XdrContext() = default;

bool XdrContext::Version(uint32_t version) {
  constexpr char kVersion[] = "@version";
  switch (op_) {
    case XdrOp::TO_JSON:
      Field(kVersion).Value(&version);
      return true;

    case XdrOp::FROM_JSON: {
      if (!value_->IsObject()) {
        AddError("Version(): must be on an Object.");
        return false;
      }
      auto i = value_->FindMember(kVersion);
      if (i == value_->MemberEnd()) {
        AddError("Version(): No @version present.");
        return false;
      }
      uint32_t actual_version{};
      Field(kVersion).Value(&actual_version);
      if (actual_version != version) {
        AddError("Version(): Found version " + std::to_string(actual_version) +
                 " but expected version " + std::to_string(version));
        return false;
      }
      return true;
    }
  }
}

void XdrContext::Value(unsigned char* const data) {
  ValueWithDefault(data, true, static_cast<unsigned char>(0));
}

void XdrContext::Value(int8_t* const data) { ValueWithDefault(data, true, static_cast<int8_t>(0)); }

void XdrContext::Value(unsigned short* const data) {
  ValueWithDefault(data, true, static_cast<unsigned short>(0));
}

void XdrContext::Value(short* const data) { ValueWithDefault(data, true, static_cast<short>(0)); }

void XdrContext::Value(fidl::StringPtr* const data) {
  ValueWithDefault(data, true, cpp17::nullopt);
}

void XdrContext::Value(std::string* const data) { ValueWithDefault(data, true, ""); }

void XdrContext::ValueWithDefault(unsigned char* const data, bool use_data,
                                  unsigned char default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      use_data ? value_->Set(static_cast<int>(*data), allocator())
               : value_->Set(static_cast<int>(default_value), allocator());
      break;

    case XdrOp::FROM_JSON:
      if (!value_->Is<int>()) {
        if (use_data) {
          AddError("Value() of unsigned char: int expected");
          return;
        }
        *data = default_value;
        return;
      }
      *data = static_cast<unsigned char>(value_->Get<int>());
      return;
  }
}

void XdrContext::ValueWithDefault(int8_t* const data, bool use_data, int8_t default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      use_data ? value_->Set(static_cast<int>(*data), allocator())
               : value_->Set(static_cast<int>(default_value), allocator());
      break;

    case XdrOp::FROM_JSON:
      if (!value_->Is<int>()) {
        if (use_data) {
          AddError("Value() of int8: int expected");
          return;
        }
        *data = default_value;
        return;
      }
      *data = static_cast<int8_t>(value_->Get<int>());
      return;
  }
}

void XdrContext::ValueWithDefault(unsigned short* const data, bool use_data,
                                  unsigned short default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      use_data ? value_->Set(static_cast<int>(*data), allocator())
               : value_->Set(static_cast<int>(default_value), allocator());
      break;

    case XdrOp::FROM_JSON:
      if (!value_->Is<int>()) {
        if (use_data) {
          AddError("Value() of unsigned short: int expected");
          return;
        }
        *data = default_value;
        return;
      }
      *data = static_cast<unsigned short>(value_->Get<int>());
      return;
  }
}

void XdrContext::ValueWithDefault(short* const data, bool use_data, short default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      use_data ? value_->Set(static_cast<int>(*data), allocator())
               : value_->Set(static_cast<int>(default_value), allocator());
      break;

    case XdrOp::FROM_JSON:
      if (!value_->Is<int>()) {
        if (use_data) {
          AddError("Value() of short: int expected");
          return;
        }
        *data = default_value;
        return;
      }
      *data = static_cast<short>(value_->Get<int>());
      return;
  }
}

void XdrContext::ValueWithDefault(fidl::StringPtr* const data, bool use_data,
                                  fidl::StringPtr default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      if (!use_data) {
        value_->SetString(default_value.has_value() ? default_value.value() : "", allocator());
        break;
      }
      data->has_value() ? value_->SetString(data->value(), allocator()) : value_->SetNull();
      break;

    case XdrOp::FROM_JSON:
      if (value_->IsNull()) {
        data->reset();
      } else if (value_->IsString()) {
        *data = value_->GetString();
      } else {
        if (use_data) {
          AddError("Value() of fidl::StringPtr: string expected");
          return;
        }
        *data = default_value;
      }
      break;
  }
}

void XdrContext::ValueWithDefault(std::string* const data, bool use_data,
                                  std::string default_value) {
  switch (op_) {
    case XdrOp::TO_JSON:
      use_data ? value_->SetString(*data, allocator())
               : value_->SetString(default_value, allocator());
      break;

    case XdrOp::FROM_JSON:
      if (value_->IsString()) {
        *data = value_->GetString();
      } else {
        if (use_data) {
          AddError("Value() of std::string: string expected");
          return;
        }
        *data = default_value;
      }
      break;
  }
}

XdrContext XdrContext::Field(const char field[]) {
  switch (op_) {
    case XdrOp::TO_JSON:
      if (!value_->IsObject()) {
        value_->SetObject();
      }
      break;

    case XdrOp::FROM_JSON:
      if (!value_->IsObject()) {
        AddError("Object expected for field " + std::string(field));
        return {this, field, op_, doc_, &null_};
      }
  }

  auto i = value_->FindMember(field);
  if (i != value_->MemberEnd()) {
    return {this, field, op_, doc_, &i->value};
  }

  switch (op_) {
    case XdrOp::TO_JSON: {
      JsonValue name{field, allocator()};
      value_->AddMember(name, JsonValue(), allocator());
      auto i = value_->FindMember(field);
      FX_DCHECK(i != value_->MemberEnd());
      return {this, field, op_, doc_, &i->value};
    }

    case XdrOp::FROM_JSON:
      return {this, field, op_, doc_, &null_};
  }
}

XdrContext XdrContext::FieldWithDefault(const char field[]) {
  switch (op_) {
    case XdrOp::TO_JSON:
      if (!value_->IsObject()) {
        value_->SetObject();
      }
      break;

    case XdrOp::FROM_JSON:
      if (!value_->IsObject()) {
        return {this, field, op_, doc_, &null_};
      }
  }

  auto i = value_->FindMember(field);
  if (i != value_->MemberEnd()) {
    return {this, field, op_, doc_, &i->value};
  }

  switch (op_) {
    case XdrOp::TO_JSON: {
      JsonValue name{field, allocator()};
      value_->AddMember(name, JsonValue(), allocator());
      auto i = value_->FindMember(field);
      FX_DCHECK(i != value_->MemberEnd());
      return {this, field, op_, doc_, &i->value};
    }

    case XdrOp::FROM_JSON:
      return {this, field, op_, doc_, &null_};
  }
}

XdrContext XdrContext::Element(const rapidjson::SizeType i) {
  switch (op_) {
    case XdrOp::TO_JSON:
      if (!value_->IsArray()) {
        value_->SetArray();
      }
      break;

    case XdrOp::FROM_JSON:
      if (!value_->IsArray()) {
        AddError("Array expected for element " + std::to_string(i));
        return {this, nullptr, op_, doc_, &null_};
      }
  }

  if (i < value_->Size()) {
    return {this, nullptr, op_, doc_, &value_->operator[](i)};
  }

  switch (op_) {
    case XdrOp::TO_JSON:
      while (i >= value_->Size()) {
        value_->PushBack(JsonValue(), allocator());
      }
      return {this, nullptr, op_, doc_, &value_->operator[](i)};

    case XdrOp::FROM_JSON:
      return {this, nullptr, op_, doc_, &null_};
  }
}

XdrContext XdrContext::ElementWithDefault(const rapidjson::SizeType i) {
  switch (op_) {
    case XdrOp::TO_JSON:
      if (!value_->IsArray()) {
        value_->SetArray();
      }
      break;

    case XdrOp::FROM_JSON:
      if (!value_->IsArray()) {
        return {this, nullptr, op_, doc_, &null_};
      }
  }

  if (i < value_->Size()) {
    return {this, nullptr, op_, doc_, &value_->operator[](i)};
  }

  switch (op_) {
    case XdrOp::TO_JSON:
      while (i >= value_->Size()) {
        value_->PushBack(JsonValue(), allocator());
      }
      return {this, nullptr, op_, doc_, &value_->operator[](i)};

    case XdrOp::FROM_JSON:
      return {this, nullptr, op_, doc_, &null_};
  }
}

void XdrContext::AddError(const std::string& message) {
  auto error = AddError();
  error->append(": " + message + "\n");
}

std::string* XdrContext::AddError() {
  std::string* const ret = parent_ ? parent_->AddError() : error_;

  if (parent_) {
    ret->append("/");
  }

  ret->append(JsonTypeName(value_->GetType()));

  if (name_) {
    ret->append(" ");
    ret->append(name_);
  }

  return ret;
}

std::string* XdrContext::GetError() { return parent_ ? parent_->GetError() : error_; }

}  // namespace modular
