/*
 * Copyright (C) 2019 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 "updater/updater_runtime.h"

#include <algorithm>
#include <chrono>
#include <iterator>
#include <optional>
#include <string>
#include <type_traits>
#include <vector>

#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <fs_mgr.h>
#include <fs_mgr_dm_linear.h>
#include <libdm/dm.h>
#include <liblp/builder.h>

using android::dm::DeviceMapper;
using android::dm::DmDeviceState;
using android::fs_mgr::CreateLogicalPartition;
using android::fs_mgr::DestroyLogicalPartition;
using android::fs_mgr::LpMetadata;
using android::fs_mgr::MetadataBuilder;
using android::fs_mgr::Partition;
using android::fs_mgr::PartitionOpener;

static constexpr std::chrono::milliseconds kMapTimeout{ 1000 };

static std::string GetSuperDevice() {
  return "/dev/block/by-name/" + fs_mgr_get_super_partition_name();
}

static bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) {
  auto state = DeviceMapper::Instance().GetState(partition_name);
  if (state == DmDeviceState::INVALID) {
    return true;
  }
  if (state == DmDeviceState::ACTIVE) {
    return DestroyLogicalPartition(partition_name, kMapTimeout);
  }
  LOG(ERROR) << "Unknown device mapper state: "
             << static_cast<std::underlying_type_t<DmDeviceState>>(state);
  return false;
}

bool UpdaterRuntime::MapPartitionOnDeviceMapper(const std::string& partition_name,
                                                std::string* path) {
  auto state = DeviceMapper::Instance().GetState(partition_name);
  if (state == DmDeviceState::INVALID) {
    return CreateLogicalPartition(GetSuperDevice(), 0 /* metadata slot */, partition_name,
                                  true /* force writable */, kMapTimeout, path);
  }

  if (state == DmDeviceState::ACTIVE) {
    return DeviceMapper::Instance().GetDmDevicePathByName(partition_name, path);
  }
  LOG(ERROR) << "Unknown device mapper state: "
             << static_cast<std::underlying_type_t<DmDeviceState>>(state);
  return false;
}

bool UpdaterRuntime::UnmapPartitionOnDeviceMapper(const std::string& partition_name) {
  return ::UnmapPartitionOnDeviceMapper(partition_name);
}

namespace {  // Ops

struct OpParameters {
  std::vector<std::string> tokens;
  MetadataBuilder* builder;

  bool ExpectArgSize(size_t size) const {
    CHECK(!tokens.empty());
    auto actual = tokens.size() - 1;
    if (actual != size) {
      LOG(ERROR) << "Op " << op() << " expects " << size << " args, got " << actual;
      return false;
    }
    return true;
  }
  const std::string& op() const {
    CHECK(!tokens.empty());
    return tokens[0];
  }
  const std::string& arg(size_t pos) const {
    CHECK_LE(pos + 1, tokens.size());
    return tokens[pos + 1];
  }
  std::optional<uint64_t> uint_arg(size_t pos, const std::string& name) const {
    auto str = arg(pos);
    uint64_t ret;
    if (!android::base::ParseUint(str, &ret)) {
      LOG(ERROR) << "Op " << op() << " expects uint64 for argument " << name << ", got " << str;
      return std::nullopt;
    }
    return ret;
  }
};

using OpFunction = std::function<bool(const OpParameters&)>;
using OpMap = std::map<std::string, OpFunction>;

bool PerformOpResize(const OpParameters& params) {
  if (!params.ExpectArgSize(2)) return false;
  const auto& partition_name = params.arg(0);
  auto size = params.uint_arg(1, "size");
  if (!size.has_value()) return false;

  auto partition = params.builder->FindPartition(partition_name);
  if (partition == nullptr) {
    LOG(ERROR) << "Failed to find partition " << partition_name
               << " in dynamic partition metadata.";
    return false;
  }
  if (!UnmapPartitionOnDeviceMapper(partition_name)) {
    LOG(ERROR) << "Cannot unmap " << partition_name << " before resizing.";
    return false;
  }
  if (!params.builder->ResizePartition(partition, size.value())) {
    LOG(ERROR) << "Failed to resize partition " << partition_name << " to size " << *size << ".";
    return false;
  }
  return true;
}

bool PerformOpRemove(const OpParameters& params) {
  if (!params.ExpectArgSize(1)) return false;
  const auto& partition_name = params.arg(0);

  if (!UnmapPartitionOnDeviceMapper(partition_name)) {
    LOG(ERROR) << "Cannot unmap " << partition_name << " before removing.";
    return false;
  }
  params.builder->RemovePartition(partition_name);
  return true;
}

bool PerformOpAdd(const OpParameters& params) {
  if (!params.ExpectArgSize(2)) return false;
  const auto& partition_name = params.arg(0);
  const auto& group_name = params.arg(1);

  if (params.builder->AddPartition(partition_name, group_name, LP_PARTITION_ATTR_READONLY) ==
      nullptr) {
    LOG(ERROR) << "Failed to add partition " << partition_name << " to group " << group_name << ".";
    return false;
  }
  return true;
}

bool PerformOpMove(const OpParameters& params) {
  if (!params.ExpectArgSize(2)) return false;
  const auto& partition_name = params.arg(0);
  const auto& new_group = params.arg(1);

  auto partition = params.builder->FindPartition(partition_name);
  if (partition == nullptr) {
    LOG(ERROR) << "Cannot move partition " << partition_name << " to group " << new_group
               << " because it is not found.";
    return false;
  }

  auto old_group = partition->group_name();
  if (old_group != new_group) {
    if (!params.builder->ChangePartitionGroup(partition, new_group)) {
      LOG(ERROR) << "Cannot move partition " << partition_name << " from group " << old_group
                 << " to group " << new_group << ".";
      return false;
    }
  }
  return true;
}

bool PerformOpAddGroup(const OpParameters& params) {
  if (!params.ExpectArgSize(2)) return false;
  const auto& group_name = params.arg(0);
  auto maximum_size = params.uint_arg(1, "maximum_size");
  if (!maximum_size.has_value()) return false;

  auto group = params.builder->FindGroup(group_name);
  if (group != nullptr) {
    LOG(ERROR) << "Cannot add group " << group_name << " because it already exists.";
    return false;
  }

  if (maximum_size.value() == 0) {
    LOG(WARNING) << "Adding group " << group_name << " with no size limits.";
  }

  if (!params.builder->AddGroup(group_name, maximum_size.value())) {
    LOG(ERROR) << "Failed to add group " << group_name << " with maximum size "
               << maximum_size.value() << ".";
    return false;
  }
  return true;
}

bool PerformOpResizeGroup(const OpParameters& params) {
  if (!params.ExpectArgSize(2)) return false;
  const auto& group_name = params.arg(0);
  auto new_size = params.uint_arg(1, "maximum_size");
  if (!new_size.has_value()) return false;

  auto group = params.builder->FindGroup(group_name);
  if (group == nullptr) {
    LOG(ERROR) << "Cannot resize group " << group_name << " because it is not found.";
    return false;
  }

  auto old_size = group->maximum_size();
  if (old_size != new_size.value()) {
    if (!params.builder->ChangeGroupSize(group_name, new_size.value())) {
      LOG(ERROR) << "Cannot resize group " << group_name << " from " << old_size << " to "
                 << new_size.value() << ".";
      return false;
    }
  }
  return true;
}

std::vector<std::string> ListPartitionNamesInGroup(MetadataBuilder* builder,
                                                   const std::string& group_name) {
  auto partitions = builder->ListPartitionsInGroup(group_name);
  std::vector<std::string> partition_names;
  std::transform(partitions.begin(), partitions.end(), std::back_inserter(partition_names),
                 [](Partition* partition) { return partition->name(); });
  return partition_names;
}

bool PerformOpRemoveGroup(const OpParameters& params) {
  if (!params.ExpectArgSize(1)) return false;
  const auto& group_name = params.arg(0);

  auto partition_names = ListPartitionNamesInGroup(params.builder, group_name);
  if (!partition_names.empty()) {
    LOG(ERROR) << "Cannot remove group " << group_name << " because it still contains partitions ["
               << android::base::Join(partition_names, ", ") << "]";
    return false;
  }
  params.builder->RemoveGroupAndPartitions(group_name);
  return true;
}

bool PerformOpRemoveAllGroups(const OpParameters& params) {
  if (!params.ExpectArgSize(0)) return false;

  auto group_names = params.builder->ListGroups();
  for (const auto& group_name : group_names) {
    auto partition_names = ListPartitionNamesInGroup(params.builder, group_name);
    for (const auto& partition_name : partition_names) {
      if (!UnmapPartitionOnDeviceMapper(partition_name)) {
        LOG(ERROR) << "Cannot unmap " << partition_name << " before removing group " << group_name
                   << ".";
        return false;
      }
    }
    params.builder->RemoveGroupAndPartitions(group_name);
  }
  return true;
}

}  // namespace

bool UpdaterRuntime::UpdateDynamicPartitions(const std::string_view op_list_value) {
  auto super_device = GetSuperDevice();
  auto builder = MetadataBuilder::New(PartitionOpener(), super_device, 0);
  if (builder == nullptr) {
    LOG(ERROR) << "Failed to load dynamic partition metadata.";
    return false;
  }

  static const OpMap op_map{
    // clang-format off
    {"resize",                PerformOpResize},
    {"remove",                PerformOpRemove},
    {"add",                   PerformOpAdd},
    {"move",                  PerformOpMove},
    {"add_group",             PerformOpAddGroup},
    {"resize_group",          PerformOpResizeGroup},
    {"remove_group",          PerformOpRemoveGroup},
    {"remove_all_groups",     PerformOpRemoveAllGroups},
    // clang-format on
  };

  std::vector<std::string> lines = android::base::Split(std::string(op_list_value), "\n");
  for (const auto& line : lines) {
    auto comment_idx = line.find('#');
    auto op_and_args = comment_idx == std::string::npos ? line : line.substr(0, comment_idx);
    op_and_args = android::base::Trim(op_and_args);
    if (op_and_args.empty()) continue;

    auto tokens = android::base::Split(op_and_args, " ");
    const auto& op = tokens[0];
    auto it = op_map.find(op);
    if (it == op_map.end()) {
      LOG(ERROR) << "Unknown operation in op_list: " << op;
      return false;
    }
    OpParameters params;
    params.tokens = tokens;
    params.builder = builder.get();
    if (!it->second(params)) {
      return false;
    }
  }

  auto metadata = builder->Export();
  if (metadata == nullptr) {
    LOG(ERROR) << "Failed to export metadata.";
    return false;
  }

  if (!UpdatePartitionTable(super_device, *metadata, 0)) {
    LOG(ERROR) << "Failed to write metadata.";
    return false;
  }

  return true;
}
