//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "misc_info.h"

#include <algorithm>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

namespace cuttlefish {

MiscInfo ParseMiscInfo(const std::string& misc_info_contents) {
  auto lines = android::base::Split(misc_info_contents, "\n");
  MiscInfo misc_info;
  for (auto& line : lines) {
    line = android::base::Trim(line);
    if (line.size() == 0) {
      continue;
    }
    auto eq_pos = line.find('=');
    if (eq_pos == std::string::npos) {
      LOG(WARNING) << "Line in unknown format: \"" << line << "\"";
      continue;
    }
    // Not using android::base::Split here to only capture the first =
    auto key = android::base::Trim(line.substr(0, eq_pos));
    auto value = android::base::Trim(line.substr(eq_pos + 1));
    if (misc_info.find(key) != misc_info.end() && misc_info[key] != value) {
      LOG(ERROR) << "Duplicate key: \"" << key << "\". First value: \""
                 << misc_info[key] << "\", Second value: \"" << value << "\"";
      return {};
    }
    misc_info[key] = value;
  }
  return misc_info;
}

std::string WriteMiscInfo(const MiscInfo& misc_info) {
  std::stringstream out;
  for (const auto& entry : misc_info) {
    out << entry.first << "=" << entry.second << "\n";
  }
  return out.str();
}

static const std::string kDynamicPartitions = "dynamic_partition_list";

std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) {
  auto value_it = info.find(kDynamicPartitions);
  if (value_it == info.end()) {
    return {};
  }
  auto components = android::base::Split(value_it->second, " ");
  for (auto& component : components) {
    component = android::base::Trim(component);
  }
  components.erase(std::remove(components.begin(), components.end(), ""),
                   components.end());
  return components;
}

static constexpr const char* kGoogleDynamicPartitions =
    "google_dynamic_partitions";
static constexpr const char* kSuperPartitionGroups = "super_partition_groups";

bool SetSuperPartitionComponents(const std::vector<std::string>& components,
                                 MiscInfo* misc_info) {
  auto super_partition_groups = misc_info->find(kSuperPartitionGroups);
  if (super_partition_groups == misc_info->end()) {
    LOG(ERROR) << "Failed to find super partition groups in misc_info";
    return false;
  }

  // Remove all existing update groups in misc_info
  auto update_groups =
      android::base::Split(super_partition_groups->second, " ");
  for (const auto& group_name : update_groups) {
    auto partition_list = android::base::StringPrintf("super_%s_partition_list",
                                                      group_name.c_str());
    auto partition_size =
        android::base::StringPrintf("super_%s_group_size", group_name.c_str());
    for (const auto& key : {partition_list, partition_size}) {
      auto it = misc_info->find(key);
      if (it == misc_info->end()) {
        LOG(ERROR) << "Failed to find " << key << " in misc_info";
        return false;
      }
      misc_info->erase(it);
    }
  }

  // For merged target-file, put all dynamic partitions under the
  // google_dynamic_partitions update group.
  // TODO(xunchang) use different update groups for system and vendor images.
  (*misc_info)[kDynamicPartitions] = android::base::Join(components, " ");
  (*misc_info)[kSuperPartitionGroups] = kGoogleDynamicPartitions;
  std::string partitions_list_key = android::base::StringPrintf(
      "super_%s_partition_list", kGoogleDynamicPartitions);
  (*misc_info)[partitions_list_key] = android::base::Join(components, " ");

  // Use the entire super partition as the group size
  std::string group_size_key = android::base::StringPrintf(
      "super_%s_group_size", kGoogleDynamicPartitions);
  auto super_size_it = misc_info->find("super_partition_size");
  if (super_size_it == misc_info->end()) {
    LOG(ERROR) << "Failed to find super partition size";
    return false;
  }
  (*misc_info)[group_size_key] = super_size_it->second;
  return true;
}

} // namespace cuttlefish
