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

#include <string>

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

#include "peridot/lib/rapidjson/rapidjson.h"

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) {
  FXL_DCHECK(doc_ != nullptr);
  FXL_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) {
  FXL_DCHECK(parent_ != nullptr);
  FXL_DCHECK(doc_ != nullptr);
  FXL_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, nullptr);
}

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.get(), allocator());
        break;
      }
      data->is_null() ? value_->SetNull()
                      : value_->SetString(data->get(), allocator());
      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);
      FXL_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);
      FXL_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 size_t 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 size_t 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
