// Copyright 2019 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 <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fuchsia/hardware/block/partition/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fit/defer.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/device/block.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include <unordered_map>

#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <gpt/c/gpt.h>
#include <gpt/guid.h>
#include <zxtest/base/log-sink.h>
#include <zxtest/zxtest.h>

#include "src/lib/fsl/io/device_watcher.h"

namespace fuchsia_partition = fuchsia_hardware_block_partition;

using devmgr_integration_test::RecursiveWaitForFile;

#define DEV_BLOCK "/dev/class/block"

class PartitionMappingTest : public zxtest::Test {
 protected:
  static void ScanBlockAndValidateMapping(
      const std::unordered_map<std::string, std::string>& mapping) {
    fbl::unique_fd devfs_root(open(DEV_BLOCK, O_RDONLY));
    ASSERT_TRUE(devfs_root);

    struct dirent* de;
    DIR* dir = opendir(DEV_BLOCK);
    ASSERT_NOT_NULL(dir);
    auto cleanup = fit::defer([&dir]() { closedir(dir); });

    while ((de = readdir(dir)) != nullptr) {
      if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
        continue;
      }

      fbl::unique_fd fd;
      EXPECT_OK(RecursiveWaitForFile(devfs_root, de->d_name, &fd), "%s/%s", DEV_BLOCK, de->d_name);
      ASSERT_TRUE(fd);
      fdio_cpp::FdioCaller caller(std::move(fd));

      std::string partition_name = GetLabel(caller);

      if (mapping.count(partition_name)) {
        std::string expected_type = mapping.at(partition_name);
        EXPECT_EQ(GetType(caller), expected_type);
      }
    }
  }

  static std::string GetType(const fdio_cpp::FdioCaller& caller) {
    auto guid_resp = fidl::WireCall<fuchsia_partition::Partition>(
                         fidl::UnownedClientEnd<fuchsia_partition::Partition>(caller.channel()))
                         .GetTypeGuid();
    if (guid_resp.ok() && guid_resp->status == ZX_OK && guid_resp->guid) {
      return gpt::KnownGuid::TypeDescription(guid_resp->guid->value.data());
    }
    return {};
  }

  static std::string GetLabel(const fdio_cpp::FdioCaller& caller) {
    auto name_resp = fidl::WireCall<fuchsia_partition::Partition>(
                         fidl::UnownedClientEnd<fuchsia_partition::Partition>(caller.channel()))
                         .GetName();
    if (name_resp.ok() && name_resp->status == ZX_OK) {
      return std::string(name_resp->name.data(), name_resp->name.size());
    }
    return {};
  }
};

TEST_F(PartitionMappingTest, NelsonPartitionMapping) {
  std::unordered_map<std::string, std::string> mapping = {
      {"misc", "misc"},         {"boot_a", "zircon-a"},     {"boot_b", "zircon-b"},
      {"cache", "zircon-r"},    {"zircon_r", "zircon-r"},   {"vbmeta_a", "vbmeta_a"},
      {"vbmeta_b", "vbmeta_b"}, {"reserved_c", "vbmeta_r"}, {"vbmeta_r", "vbmeta_r"},
      {"fvm", "fuchsia-fvm"},
  };
  ScanBlockAndValidateMapping(mapping);
}
