// Copyright 2017 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 <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <zircon/assert.h>
#include <zircon/device/block.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <chromeos-disk-setup/chromeos-disk-setup.h>
#include <gpt/cros.h>
#include <gpt/gpt.h>

namespace chromeos_disk_setup {
using gpt::GptDevice;
namespace {

constexpr uint8_t kFvmGuid[GPT_GUID_LEN] = GUID_FVM_VALUE;
constexpr uint8_t kKernGuid[GPT_GUID_LEN] = GUID_CROS_KERNEL_VALUE;
constexpr uint8_t kRootGuid[GPT_GUID_LEN] = GUID_CROS_ROOT_VALUE;
constexpr uint8_t kStateCrosGuid[GPT_GUID_LEN] = GUID_CROS_STATE_VALUE;
constexpr uint8_t kStateLinuxGuid[GPT_GUID_LEN] = GUID_LINUX_FILESYSTEM_DATA_VALUE;
constexpr uint8_t kSysCfgGuid[GPT_GUID_LEN] = GUID_SYS_CONFIG_VALUE;

// this value is shared with device-partitioner.cpp
constexpr uint64_t kMinFvmSize = 8LU * (1 << 30);

constexpr uint64_t kSysCfgSize = 1 << 20;

// part_name_eql compares the name field in the given partition to the cstring
// name, returning true if the partition name is equal to name and zero-padded.
bool part_name_eql(const gpt_partition_t* part, const char* name) {
  if (part == NULL) {
    return false;
  }
  char buf[GPT_NAME_LEN] = {0};
  utf16_to_cstring(&buf[0], (const uint16_t*)part->name, GPT_NAME_LEN / 2);
  // We use a case-insenstive comparison to be compatible with the previous naming scheme.
  // On a ChromeOS device, all of the kernel partitions share a common GUID type, so we
  // distinguish Zircon kernel partitions based on name.
  return !strncasecmp(buf, name, GPT_NAME_LEN);
}

// part_name_guid_eql returns true if the given partition has the given name and
// the given type GUID, false otherwise.
bool part_name_guid_eql(const gpt_partition_t* part, const char* name,
                        const uint8_t guid[GPT_GUID_LEN]) {
  if (part == NULL) {
    return false;
  }
  if (!memcmp(part->type, &guid[0], GPT_GUID_LEN) && part_name_eql(part, name)) {
    return true;
  }
  return false;
}

// part_size_gte returns true if the partition size is greater than or equal to
// the size given, false otherwise.
bool part_size_gte(gpt_partition_t* part, uint64_t size, uint64_t block_size) {
  if (part == NULL) {
    return false;
  }
  uint64_t size_in_blocks = part->last - part->first + 1;
  return size_in_blocks * block_size >= size;
}

// find_by_type finds the first partition matching the given type guid.
gpt_partition_t* find_by_type(const GptDevice* gpt, const uint8_t type_guid[GPT_GUID_LEN]) {
  for (uint32_t i = 0; i < gpt::kPartitionCount; ++i) {
    gpt_partition_t* p = gpt->GetPartition(i);
    if (p == NULL) {
      continue;
    }
    if (!memcmp(p->type, &type_guid[0], GPT_GUID_LEN)) {
      return p;
    }
  }
  return NULL;
}

// find_by_type_and_name finds the first partition matching the given type guid and name.
gpt_partition_t* find_by_type_and_name(const GptDevice* gpt, const uint8_t type_guid[GPT_GUID_LEN],
                                       const char* name) {
  for (uint32_t i = 0; i < gpt::kPartitionCount; ++i) {
    gpt_partition_t* p = gpt->GetPartition(i);
    if (p == NULL) {
      continue;
    }
    if (part_name_guid_eql(p, name, type_guid)) {
      return p;
    }
  }
  return NULL;
}

// Find a contiguous run of free space on the disk at least blocks_req in length.
// If space is found, true is returned and out_hole_start and out_hole_end
// contain the first free and last free blocks in a contiguous run.
bool find_space(GptDevice* gpt, const uint64_t blocks_req, uint64_t* out_hole_start,
                uint64_t* out_hole_end) {
  gpt_partition_t* parts[gpt::kPartitionCount] = {0};
  for (uint32_t i = 0; i < gpt::kPartitionCount; i++) {
    parts[i] = gpt->GetPartition(i);
  }

  // XXX(raggi): once the lib supports more and less than gpt::kPartitionCount,
  // this will need to be fixed (as will many loops).
  gpt_sort_partitions(parts, gpt::kPartitionCount);

  uint64_t first_usable, last_usable;
  ZX_ASSERT(gpt->Range(&first_usable, &last_usable) == ZX_OK);

  uint64_t prev_end = first_usable - 1;
  for (uint32_t i = 0; i < gpt::kPartitionCount; i++) {
    if (parts[i] == NULL) {
      continue;
    }

    // TODO(raggi): find out how the tests end up making this state
    if (parts[i]->first >= last_usable || parts[i]->last >= last_usable) {
      break;
    }

    uint64_t gap = parts[i]->first - (prev_end + 1);
    if (gap >= blocks_req) {
      *out_hole_start = prev_end + 1;
      *out_hole_end = parts[i]->first - 1;

      return true;
    }
    prev_end = parts[i]->last;
  }

  if (prev_end < last_usable && last_usable - (prev_end + 1) >= blocks_req) {
    *out_hole_start = prev_end + 1;
    *out_hole_end = last_usable;

    return true;
  }

  return false;
}

// create a GPT entry with the supplied attributes and assign it a random
// GUID. May return an error if the GUID can not be generated for the partition
// or operations on the gpt_device_t fail.
zx_status_t create_gpt_entry(GptDevice* gpt, const uint64_t first, const uint64_t blks,
                             const uint8_t type[GPT_GUID_LEN], const char* name) {
  uint8_t guid[GPT_GUID_LEN];
  zx_cprng_draw(guid, GPT_GUID_LEN);

  uint8_t tguid[GPT_GUID_LEN];
  memcpy(&tguid, type, GPT_GUID_LEN);
  if (gpt->AddPartition(name, tguid, guid, first, blks, 0) != ZX_OK) {
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}

}  // namespace

__BEGIN_CDECLS

bool is_cros(const GptDevice* gpt) {
  uint8_t roots = 0;
  uint8_t kerns = 0;
  bool state = false;

  for (uint32_t i = 0; i < gpt::kPartitionCount; ++i) {
    gpt_partition_t* p = gpt->GetPartition(i);
    if (p == NULL) {
      continue;
    }

    if (!memcmp(p->type, kRootGuid, GPT_GUID_LEN) &&
        (part_name_eql(p, "ROOT-A") || part_name_eql(p, "ROOT-B"))) {
      roots++;
    } else if (!memcmp(p->type, kKernGuid, GPT_GUID_LEN) &&
               (part_name_eql(p, "KERN-A") || part_name_eql(p, "KERN-B"))) {
      kerns++;
    } else if ((!memcmp(p->type, kStateCrosGuid, GPT_GUID_LEN) ||
                !memcmp(p->type, kStateLinuxGuid, GPT_GUID_LEN)) &&
               part_name_eql(p, "STATE")) {
      // Note that STATE GUID type can either be cros_data or, in the case of a
      // freshly recovered device, linux_filesystem
      state = true;
    }
  }

  return state && roots >= 2 && kerns >= 2;
}

// is_ready_to_pave returns true if there exist partitions for:
// * ZIRCON-A is a GUID_CROS_KERNEL_VALUE at least sz_kern in size.
// * ZIRCON-B is a GUID_CROS_KERNEL_VALUE at least sz_kern in size.
// * ZIRCON-R is a GUID_CROS_KERNEL_VALUE at least sz_kern in size.
// * FVM      is a GUID_FVM_VALUE         at least sz_kern * 8 in size
bool is_ready_to_pave(const GptDevice* gpt, const fuchsia_hardware_block_BlockInfo* blk_info,
                      const uint64_t sz_kern) {
  bool found_zircon_a = false, found_zircon_b = false, found_zircon_r = false;
  bool found_fvm = false, found_syscfg = false;

  for (uint32_t i = 0; i < gpt::kPartitionCount; i++) {
    gpt_partition_t* part = gpt->GetPartition(i);
    if (part == NULL) {
      continue;
    }
    if (!memcmp(part->type, kFvmGuid, GPT_GUID_LEN)) {
      if (!part_size_gte(part, kMinFvmSize, blk_info->block_size)) {
        continue;
      }
      found_fvm = true;
      continue;
    }
    if (!memcmp(part->type, kKernGuid, GPT_GUID_LEN)) {
      if (!part_size_gte(part, sz_kern, blk_info->block_size)) {
        continue;
      }
      if (part_name_eql(part, "ZIRCON-A")) {
        found_zircon_a = true;
      }
      if (part_name_eql(part, "ZIRCON-B")) {
        found_zircon_b = true;
      }
      if (part_name_eql(part, "ZIRCON-R")) {
        found_zircon_r = true;
      }
    }
    if (!memcmp(part->type, kSysCfgGuid, GPT_GUID_LEN)) {
      if (!part_size_gte(part, kSysCfgSize, blk_info->block_size)) {
        continue;
      }
      found_syscfg = true;
    }
  }
  if (!found_syscfg) {
    printf("cros-disk-setup: missing syscfg (or insufficient size)\n");
  }
  if (!found_fvm) {
    printf("cros-disk-setup: missing FVM (or insufficient size)\n");
  }
  if (!found_zircon_a || !found_zircon_b || !found_zircon_r) {
    printf("cros-disk-setup: missing one or more kernel partitions\n");
  }

  return found_zircon_a && found_zircon_b && found_zircon_r && found_fvm && found_syscfg;
}

zx_status_t config_cros_for_fuchsia(GptDevice* gpt,
                                    const fuchsia_hardware_block_BlockInfo* blk_info,
                                    const uint64_t sz_kern) {
  // TODO(raggi): this ends up getting called twice, as the canonical user,
  // the paver, calls is_ready_to_pave itself in order to determine first
  // whether it will need to sync the gpt.
  if (is_ready_to_pave(gpt, blk_info, sz_kern)) {
    return ZX_OK;
  }

  // TODO(ZX-1396): The gpt_device_t may not be valid for modification if it
  // is a newly initialized GPT which has never had gpt_device_finalize or
  // gpt_device_sync called.
  if (gpt->Finalize() != ZX_OK) {
    return ZX_ERR_INTERNAL;
  }

  // Remove the pre-existing Fuchsia partitions as when we were not already
  // pave-able and we're paving, assume that we want to tend toward a golden
  // layout. This also avoids any additional complexity that could arise from
  // intermediate gaps between these partitions.

  gpt_partition_t* p;
  if ((p = find_by_type_and_name(gpt, kKernGuid, "ZIRCON-A")) != NULL) {
    ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
  }
  if ((p = find_by_type_and_name(gpt, kKernGuid, "ZIRCON-B")) != NULL) {
    ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
  }
  if ((p = find_by_type_and_name(gpt, kKernGuid, "ZIRCON-R")) != NULL) {
    ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
  }
  if ((p = find_by_type(gpt, kFvmGuid)) != NULL) {
    ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
  }
  if ((p = find_by_type_and_name(gpt, kSysCfgGuid, "SYSCFG")) != NULL) {
    ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
  }

  // Space is required for 3 kernel partitions and one FVM partition that is
  // at least 8 kernels in size.
  uint64_t needed_space = sz_kern * 3 + kMinFvmSize + kSysCfgSize;

  // see if a contiguous block of space is available for space needed
  uint64_t blocks_needed = howmany(needed_space, blk_info->block_size);

  uint64_t hole_start, hole_end;
  bool found_hole = find_space(gpt, blocks_needed, &hole_start, &hole_end);

  // TODO(raggi): find a good heuristic to detect "old-paver" behavior, and if
  // we can detect that, remove the -C's, otherwise leave them alone.

  // First try removing the kernc and rootc partitions, as they're often a good fit for us:
  if (!found_hole) {
    // Some partitions were not large enough. If we found a KERN-C or a ROOT-C, delete them:
    if ((p = find_by_type_and_name(gpt, kKernGuid, "KERN-C")) != NULL) {
      ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
    }
    if ((p = find_by_type_and_name(gpt, kRootGuid, "ROOT-C")) != NULL) {
      ZX_ASSERT(gpt->RemovePartition(p->guid) == ZX_OK);
    }

    found_hole = find_space(gpt, blocks_needed, &hole_start, &hole_end);
  }

  // Still not enough contiguous space is available on disk, try shrinking STATE
  // Note STATE type GUID can either be cros_data or, in the case of a freshly
  // recovered device, linux_filesystem
  if (!found_hole && (((p = find_by_type_and_name(gpt, kStateCrosGuid, "STATE")) != NULL) ||
                      (p = find_by_type_and_name(gpt, kStateLinuxGuid, "STATE")) != NULL)) {
    uint64_t min_state_sz_blks = howmany(MIN_SZ_STATE, blk_info->block_size);

    // TODO (TO-607) consider if there is free space on either side of STATE

    // The STATE partition is expected to be at the end of the GPT in cros,
    // and can be shrunk in order to make space for use cases such as this.
    // Here we first try to make the partition half of it's current size
    // (pinned to a minimum of min_sz_blks). This gives us a roughly equal
    // share of the free space on the disk.

    uint64_t state_part_blks = (p->last - p->first) + 1;
    uint64_t new_state_part_blks = state_part_blks / 2;
    if (new_state_part_blks < min_state_sz_blks) {
      new_state_part_blks = min_state_sz_blks;
    }
    uint64_t new_free_blks = state_part_blks - new_state_part_blks;

    if (new_free_blks >= blocks_needed) {
      p->first = p->first + new_free_blks;

      // find_space is re-run here as there is often a chunk of free space
      // left before the STATE partition that is not big enough for us to
      // fit, but is sensible to use which would not be used simply by
      // using the state->first offset.
      found_hole = find_space(gpt, blocks_needed, &hole_start, &hole_end);
    }
  }

  if (!found_hole) {
    return ZX_ERR_NO_SPACE;
  }

  printf("cros-disk-setup: Creating SYSCFG\n");
  zx_status_t status;
  uint64_t sz_syscfg_blks = howmany(kSysCfgSize, blk_info->block_size);
  if ((status = create_gpt_entry(gpt, hole_start, sz_syscfg_blks, kSysCfgGuid, "SYSCFG")) !=
      ZX_OK) {
    printf("cros-disk-setup: Error creating SYSCFG: %d\n", status);
    return ZX_ERR_INTERNAL;
  }
  hole_start += sz_syscfg_blks;

  uint64_t sz_kern_blks = howmany(sz_kern, blk_info->block_size);

  // Create GPT entries for ZIRCON-A, ZIRCON-B, ZIRCON-R and FVM if needed.
  const char* kernel_names[3] = {"ZIRCON-A", "ZIRCON-B", "ZIRCON-R"};
  for (size_t i = 0; i < 3; ++i) {
    printf("cros-disk-setup: Creating %s\n", kernel_names[i]);
    if ((status = create_gpt_entry(gpt, hole_start, sz_kern_blks, kKernGuid, kernel_names[i])) !=
        ZX_OK) {
      printf("cros-disk-setup: Error creating %s: %d\n", kernel_names[i], status);
      return ZX_ERR_INTERNAL;
    }
    hole_start += sz_kern_blks;
  }

  printf("cros-disk-setup: Creating FVM\n");

  // TODO(raggi): add this after the test setup supports it.
  // // clear the FVM superblock to ensure that a new FVM will be created there.
  // if (gpt_partition_clear(gpt, hole_start, 1) != 0) {
  //     printf("Error clearing FVM superblock.\n");
  //     return ZX_ERR_INTERNAL;
  // }

  // The created FVM partition will fill the available free space.
  if ((status = create_gpt_entry(gpt, hole_start, (hole_end - hole_start), kFvmGuid, "fvm")) !=
      ZX_OK) {
    printf("cros-disk-setup: Error creating FVM\n");
    return status;
  }

  // TODO(raggi): add this once the test setup supports it.
  // if (!gpt_device_finalize(gpt)) {
  //     printf("Error finalizing GPT\n");
  //     return ZX_ERR_INTERNAL;
  // }
  return ZX_OK;
}

__END_CDECLS

}  // namespace chromeos_disk_setup
