// 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 "src/storage/volume_image/partition.h"

#include <sstream>

#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "src/storage/volume_image/address_descriptor.h"
#include "src/storage/volume_image/volume_descriptor.h"

namespace storage::volume_image {

bool Partition::LessThan::operator()(const Partition& lhs, const Partition& rhs) const {
  return std::tie(lhs.volume().name, lhs.volume().instance) <
         std::tie(rhs.volume().name, rhs.volume().instance);
}

fit::result<Partition, std::string> Partition::Create(std::string_view serialized_volume_image,
                                                      std::unique_ptr<Reader> reader) {
  rapidjson::Document document;
  rapidjson::ParseResult result =
      document.Parse(reinterpret_cast<const char*>(serialized_volume_image.data()),
                     serialized_volume_image.size());

  if (result.IsError()) {
    std::ostringstream error;
    error << "Error parsing serialized VolumeDescriptor. "
          << rapidjson::GetParseError_En(result.Code()) << std::endl;
    return fit::error(error.str());
  }

  if (!document.HasMember("volume")) {
    return fit::error("volume_image missing volume_descriptor field 'volume'.");
  }

  if (!document.HasMember("address")) {
    return fit::error("volume_image missing address_descriptor field 'address'.");
  }

  rapidjson::StringBuffer buffer;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  document["volume"].Accept(writer);
  auto volume_descriptor_result =
      VolumeDescriptor::Deserialize(std::string_view(buffer.GetString()));
  if (volume_descriptor_result.is_error()) {
    return volume_descriptor_result.take_error_result();
  }

  buffer.Clear();
  writer.Reset(buffer);
  document["address"].Accept(writer);
  auto address_descriptor_result =
      AddressDescriptor::Deserialize(std::string_view(buffer.GetString()));
  if (address_descriptor_result.is_error()) {
    return address_descriptor_result.take_error_result();
  }

  return fit::ok(Partition(volume_descriptor_result.take_value(),
                           address_descriptor_result.take_value(), std::move(reader)));
}

}  // namespace storage::volume_image
