// Copyright 2018 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 <memory>
#include <utility>

#include <base/json/json_string_value_serializer.h>
#include <base/strings/string_number_conversions.h>

#include "imageloader/manifest.h"

namespace imageloader {

namespace {
// The current version of the manifest file.
constexpr int kCurrentManifestVersion = 1;
// The name of the version field in the manifest.
constexpr char kManifestVersionField[] = "manifest-version";
// The name of the component version field in the manifest.
constexpr char kVersionField[] = "version";
// The name of the field containing the image hash.
constexpr char kImageHashField[] = "image-sha256-hash";
// The name of the bool field indicating whether component is removable.
constexpr char kIsRemovableField[] = "is-removable";
// The name of the metadata field.
constexpr char kMetadataField[] = "metadata";
// The name of the field containing the table hash.
constexpr char kTableHashField[] = "table-sha256-hash";
// Optional manifest fields.
constexpr char kFSType[] = "fs-type";
constexpr char kId[] = "id";
constexpr char kPackage[] = "package";
constexpr char kName[] = "name";
constexpr char kImageType[] = "image-type";
constexpr char kPreallocatedSize[] = "pre-allocated-size";
constexpr char kSize[] = "size";
constexpr char kPreloadAllowed[] = "preload-allowed";
constexpr char kMountFileRequired[] = "mount-file-required";
constexpr char kUsedBy[] = "used-by";
constexpr char kDescription[] = "description";

bool GetSHA256FromString(const std::string& hash_str,
                         std::vector<uint8_t>* bytes) {
  if (!base::HexStringToBytes(hash_str, bytes))
    return false;
  return bytes->size() == 32;
}

// Ensure the metadata entry is a dictionary mapping strings to strings and
// parse it into |out_metadata| and return true if so.
bool ParseMetadata(const base::Value* metadata_element,
                   std::map<std::string, std::string>* out_metadata) {
  DCHECK(out_metadata);

  const base::DictionaryValue* metadata_dict = nullptr;
  if (!metadata_element->GetAsDictionary(&metadata_dict))
    return false;

  base::DictionaryValue::Iterator it(*metadata_dict);
  for (; !it.IsAtEnd(); it.Advance()) {
    std::string parsed_value;
    if (!it.value().GetAsString(&parsed_value)) {
      LOG(ERROR) << "Key \"" << it.key() << "\" did not map to string value";
      return false;
    }

    (*out_metadata)[it.key()] = std::move(parsed_value);
  }

  return true;
}

}  // namespace

Manifest::Manifest()
    : manifest_version_(0),
      fs_type_(FileSystem::kExt4),
      preallocated_size_(0),
      size_(0),
      is_removable_(false) {}

bool Manifest::ParseManifest(const std::string& manifest_raw) {
  // Now deserialize the manifest json and read out the rest of the component.
  int error_code;
  std::string error_message;
  JSONStringValueDeserializer deserializer(manifest_raw);
  std::unique_ptr<base::Value> value =
      deserializer.Deserialize(&error_code, &error_message);

  if (!value) {
    LOG(ERROR) << "Could not deserialize the manifest file. Error "
               << error_code << ": " << error_message;
    return false;
  }

  base::DictionaryValue* manifest_dict = nullptr;
  if (!value->GetAsDictionary(&manifest_dict)) {
    LOG(ERROR) << "Could not parse manifest file as JSON.";
    return false;
  }

  // This will have to be changed if the manifest version is bumped.
  int version;
  if (!manifest_dict->GetInteger(kManifestVersionField, &version)) {
    LOG(ERROR) << "Could not parse manifest version field from manifest.";
    return false;
  }
  if (version != kCurrentManifestVersion) {
    LOG(ERROR) << "Unsupported version of the manifest.";
    return false;
  }
  manifest_version_ = version;

  std::string image_hash_str;
  if (!manifest_dict->GetString(kImageHashField, &image_hash_str)) {
    LOG(ERROR) << "Could not parse image hash from manifest.";
    return false;
  }

  if (!GetSHA256FromString(image_hash_str, &(image_sha256_))) {
    LOG(ERROR) << "Could not convert image hash to bytes.";
    return false;
  }

  std::string table_hash_str;
  if (!manifest_dict->GetString(kTableHashField, &table_hash_str)) {
    LOG(ERROR) << "Could not parse table hash from manifest.";
    return false;
  }

  if (!GetSHA256FromString(table_hash_str, &(table_sha256_))) {
    LOG(ERROR) << "Could not convert table hash to bytes.";
    return false;
  }

  if (!manifest_dict->GetString(kVersionField, &(version_))) {
    LOG(ERROR) << "Could not parse component version from manifest.";
    return false;
  }

  // The fs_type field is optional, and squashfs by default.
  fs_type_ = FileSystem::kSquashFS;
  std::string fs_type;
  if (manifest_dict->GetString(kFSType, &fs_type)) {
    if (fs_type == "ext4") {
      fs_type_ = FileSystem::kExt4;
    } else if (fs_type == "squashfs") {
      fs_type_ = FileSystem::kSquashFS;
    } else {
      LOG(ERROR) << "Unsupported file system type: " << fs_type;
      return false;
    }
  }

  if (!manifest_dict->GetBoolean(kIsRemovableField, &is_removable_)) {
    // If |is-removable| field does not exist, by default it is false.
    is_removable_ = false;
  }

  if (!manifest_dict->GetBoolean(kPreloadAllowed, &preload_allowed_)) {
    // If |preaload-allowed| field does not exist, by default it is false.
    preload_allowed_ = false;
  }

  if (!manifest_dict->GetBoolean(kMountFileRequired, &mount_file_required_)) {
    // If 'mount-file-required' field does not exist, by default it is false.
    mount_file_required_ = false;
  }

  // All of these fields are optional.
  manifest_dict->GetString(kId, &id_);
  manifest_dict->GetString(kPackage, &package_);
  manifest_dict->GetString(kName, &name_);
  manifest_dict->GetString(kImageType, &image_type_);
  manifest_dict->GetString(kUsedBy, &used_by_);
  manifest_dict->GetString(kDescription, &description_);

  std::string preallocated_size_str;
  if (manifest_dict->GetString(kPreallocatedSize, &preallocated_size_str)) {
    if (!base::StringToInt64(preallocated_size_str, &preallocated_size_)) {
      LOG(ERROR) << "Manifest pre-allocated-size was malformed: "
                 << preallocated_size_str;
      return false;
    }
  }

  std::string size_str;
  if (manifest_dict->GetString(kSize, &size_str)) {
    if (!base::StringToInt64(size_str, &size_)) {
      LOG(ERROR) << "Manifest size was malformed: " << size_str;
      return false;
    }
  }

  // Copy out the metadata, if it's there.
  const base::Value* metadata = nullptr;
  if (manifest_dict->Get(kMetadataField, &metadata)) {
    if (!ParseMetadata(metadata, &metadata_)) {
      LOG(ERROR) << "Manifest metadata was malformed";
      return false;
    }
  }

  return true;
}

}  // namespace imageloader
