// Copyright (c) 2012 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.

#define __STDC_FORMAT_MACROS

#include <string.h>

#include "cgpt.h"
#include "cgptlib_internal.h"
#include "crc32.h"
#include "vboot_host.h"

/* Generate output like:
 *
 *  [AB-CD-EF-01]   for group = 1
 *  [ABCD-EF01]     for group = 3  (low byte first)
 *
 * Needs (size*3-1+3) bytes of space in 'buf' (included the tailing '\0').
 */
#define BUFFER_SIZE(size) (size *3 - 1 + 3)
static short Uint8To2Chars(const uint8_t t) {
  int h = t >> 4;
  int l = t & 0xf;
  h = (h >= 0xA) ? h - 0xA + 'A' : h + '0';
  l = (l >= 0xA) ? l - 0xA + 'A' : l + '0';
  return (h << 8) + l;
}

static void RawDump(const uint8_t *memory, const int size,
                    char *buf, int group) {
  int i, outlen = 0;
  buf[outlen++] = '[';
  for (i = 0; i < size; ++i) {
    short c2 = Uint8To2Chars(memory[i]);
    buf[outlen++] = c2 >> 8;
    buf[outlen++] = c2 & 0xff;
    if (i != (size - 1) && ((i + 1) % group) == 0)
      buf[outlen++] = '-';
  }
  buf[outlen++] = ']';
  buf[outlen++] = '\0';
}

/* Output formatters */
#define TITLE_FMT      "%12s%12s%8s  %s\n"
#define GPT_FMT        "%12"PRId64"%12"PRId64"%8s  %s\n"
#define GPT_MORE       "%12s%12s%8s  ", "", "", ""
#define PARTITION_FMT  "%12"PRId64"%12"PRId64"%8d  %s\n"
#define PARTITION_MORE "%12s%12s%8s  %s%s\n", "", "", ""

static void PrintSignature(const char *indent, const char *sig, size_t n,
                           int raw) {
  size_t i;
  printf("%sSig: ", indent);
  if (!raw) {
    printf("[");
    for (i = 0; i < n; ++i)
      printf("%c", sig[i]);
    printf("]");
  } else {
    char *buf = malloc(BUFFER_SIZE(n));
    RawDump((uint8_t *)sig, n, buf, 1);
    printf("%s", buf);
    free(buf);
  }
  printf("\n");
}

static void HeaderDetails(GptHeader *header, GptEntry *entries,
                          const char *indent, int raw) {
  PrintSignature(indent, header->signature, sizeof(header->signature), raw);

  printf("%sRev: 0x%08x\n", indent, header->revision);
  printf("%sSize: %d\n", indent, header->size);
  printf("%sHeader CRC: 0x%08x %s\n", indent, header->header_crc32,
         (HeaderCrc(header) != header->header_crc32) ? "(INVALID)" : "");
  printf("%sMy LBA: %lld\n", indent, (long long)header->my_lba);
  printf("%sAlternate LBA: %lld\n", indent, (long long)header->alternate_lba);
  printf("%sFirst LBA: %lld\n", indent, (long long)header->first_usable_lba);
  printf("%sLast LBA: %lld\n", indent, (long long)header->last_usable_lba);

  {  /* For disk guid */
    char buf[GUID_STRLEN];
    GuidToStr(&header->disk_uuid, buf, GUID_STRLEN);
    printf("%sDisk UUID: %s\n", indent, buf);
  }

  printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba);
  printf("%sNumber of entries: %d\n", indent, header->number_of_entries);
  printf("%sSize of entry: %d\n", indent, header->size_of_entry);
  printf("%sEntries CRC: 0x%08x %s\n", indent, header->entries_crc32,
         header->entries_crc32 !=
             Crc32((const uint8_t *)entries,header->size_of_entry *
                                            header->number_of_entries)
             ? "INVALID" : ""
         );
}

void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
  char contents[256];                   // scratch buffer for formatting output
  uint8_t label[GPT_PARTNAME_LEN];
  char type[GUID_STRLEN], unique[GUID_STRLEN];
  int clen;

  UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]),
              label, sizeof(label));
  require(snprintf(contents, sizeof(contents),
                   "Label: \"%s\"", label) < sizeof(contents));
  printf(PARTITION_FMT, (uint64_t)entry->starting_lba,
         (uint64_t)(entry->ending_lba - entry->starting_lba + 1),
         index+1, contents);

  if (!raw && CGPT_OK == ResolveType(&entry->type, type)) {
    printf(PARTITION_MORE, "Type: ", type);
  } else {
    GuidToStr(&entry->type, type, GUID_STRLEN);
    printf(PARTITION_MORE, "Type: ", type);
  }
  GuidToStr(&entry->unique, unique, GUID_STRLEN);
  printf(PARTITION_MORE, "UUID: ", unique);

  clen = 0;
  if (!raw) {
    if (GuidEqual(&guid_chromeos_kernel, &entry->type)) {
      int tries = (entry->attrs.fields.gpt_att &
                   CGPT_ATTRIBUTE_TRIES_MASK) >>
          CGPT_ATTRIBUTE_TRIES_OFFSET;
      int successful = (entry->attrs.fields.gpt_att &
                        CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
          CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
      int priority = (entry->attrs.fields.gpt_att &
                      CGPT_ATTRIBUTE_PRIORITY_MASK) >>
          CGPT_ATTRIBUTE_PRIORITY_OFFSET;
      clen = snprintf(contents, sizeof(contents),
                      "priority=%d tries=%d successful=%d ",
                      priority, tries, successful);
    }

    if (entry->attrs.fields.required) {
      clen += snprintf(contents + clen, sizeof(contents) - clen,
                       "required=%d ", entry->attrs.fields.required);
      require(clen < sizeof(contents));
    }

    if (entry->attrs.fields.efi_ignore) {
      clen += snprintf(contents + clen, sizeof(contents) - clen,
                       "efi_ignore=%d ", entry->attrs.fields.efi_ignore);
      require(clen < sizeof(contents));
    }

    if (entry->attrs.fields.legacy_boot) {
      clen += snprintf(contents + clen, sizeof(contents) - clen,
                       "legacy_boot=%d ", entry->attrs.fields.legacy_boot);
      require(clen < sizeof(contents));
    }
  } else {
    clen = snprintf(contents, sizeof(contents),
                    "[%x]", entry->attrs.fields.gpt_att);
  }
  require(clen < sizeof(contents));
  if (clen)
    printf(PARTITION_MORE, "Attr: ", contents);
}

static void EntriesDetails(struct drive *drive, const int secondary, int raw) {
  uint32_t i;

  for (i = 0; i < GetNumberOfEntries(drive); ++i) {
    GptEntry *entry;
    entry = GetEntry(&drive->gpt, secondary, i);

    if (GuidIsZero(&entry->type))
      continue;

    EntryDetails(entry, i, raw);
  }
}

static int GptShow(struct drive *drive, CgptShowParams *params) {
  int gpt_retval;
  if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
    Error("GptSanityCheck() returned %d: %s\n",
          gpt_retval, GptError(gpt_retval));
    return CGPT_FAILED;
  }

  if (params->partition) {                      // show single partition

    if (params->partition > GetNumberOfEntries(drive)) {
      Error("invalid partition number: %d\n", params->partition);
      return CGPT_FAILED;
    }

    uint32_t index = params->partition - 1;
    GptEntry *entry = GetEntry(&drive->gpt, ANY_VALID, index);
    char buf[256];                      // scratch buffer for string conversion

    if (params->single_item) {
      switch(params->single_item) {
      case 'b':
        printf("%" PRId64 "\n", entry->starting_lba);
        break;
      case 's': {
        uint64_t size = 0;
        // If these aren't actually defined, don't show anything
        if (entry->ending_lba || entry->starting_lba)
          size = entry->ending_lba - entry->starting_lba + 1;
        printf("%" PRId64 "\n", size);
        break;
      }
      case 't':
        GuidToStr(&entry->type, buf, sizeof(buf));
        printf("%s\n", buf);
        break;
      case 'u':
        GuidToStr(&entry->unique, buf, sizeof(buf));
        printf("%s\n", buf);
        break;
      case 'l':
        UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]),
                    (uint8_t *)buf, sizeof(buf));
        printf("%s\n", buf);
        break;
      case 'S':
        printf("%d\n", GetSuccessful(drive, ANY_VALID, index));
        break;
      case 'T':
        printf("%d\n", GetTries(drive, ANY_VALID, index));
        break;
      case 'P':
        printf("%d\n", GetPriority(drive, ANY_VALID, index));
        break;
      case 'R':
        printf("%d\n", GetRequired(drive, ANY_VALID, index));
        break;
      case 'B':
        printf("%d\n", GetLegacyBoot(drive, ANY_VALID, index));
        break;
      case 'A':
        printf("0x%x\n", entry->attrs.fields.gpt_att);
        break;
      }
    } else {
      printf(TITLE_FMT, "start", "size", "part", "contents");
      EntryDetails(entry, index, params->numeric);
    }

  } else if (params->quick) {                   // show all partitions, quickly
    uint32_t i;
    GptEntry *entry;
    char type[GUID_STRLEN];

    for (i = 0; i < GetNumberOfEntries(drive); ++i) {
      entry = GetEntry(&drive->gpt, ANY_VALID, i);

      if (GuidIsZero(&entry->type))
        continue;

      if (!params->numeric && CGPT_OK == ResolveType(&entry->type, type)) {
      } else {
        GuidToStr(&entry->type, type, GUID_STRLEN);
      }
      printf(PARTITION_FMT, (uint64_t)entry->starting_lba,
             (uint64_t)(entry->ending_lba - entry->starting_lba + 1),
             i+1, type);
    }
  } else {                              // show all partitions
    GptEntry *entries;

    if (CGPT_OK != ReadPMBR(drive)) {
      Error("Unable to read PMBR\n");
      return CGPT_FAILED;
    }

    printf(TITLE_FMT, "start", "size", "part", "contents");
    char buf[256];                      // buffer for formatted PMBR content
    PMBRToStr(&drive->pmbr, buf, sizeof(buf)); // will exit if buf is too small
    printf(GPT_FMT, (uint64_t)0, (uint64_t)GPT_PMBR_SECTORS, "", buf);

    if (drive->gpt.ignored & MASK_PRIMARY) {
      printf(GPT_FMT, (uint64_t)GPT_PMBR_SECTORS,
             (uint64_t)GPT_HEADER_SECTORS, "IGNORED", "Pri GPT header");
    } else {
      if (drive->gpt.valid_headers & MASK_PRIMARY) {
        printf(GPT_FMT, (uint64_t)GPT_PMBR_SECTORS,
               (uint64_t)GPT_HEADER_SECTORS, "", "Pri GPT header");
      } else {
        printf(GPT_FMT, (uint64_t)GPT_PMBR_SECTORS,
               (uint64_t)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header");
      }

      if (params->debug ||
          ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) {
        GptHeader *header;
        char indent[64];

        require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
        header = (GptHeader*)drive->gpt.primary_header;
        entries = (GptEntry*)drive->gpt.primary_entries;
        HeaderDetails(header, entries, indent, params->numeric);
      }

      GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
      printf(GPT_FMT, (uint64_t)primary_header->entries_lba,
             (uint64_t)CalculateEntriesSectors(primary_header,
                         drive->gpt.sector_bytes),
             drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
             "Pri GPT table");

      if (params->debug ||
          (drive->gpt.valid_entries & MASK_PRIMARY))
        EntriesDetails(drive, PRIMARY, params->numeric);
    }

    /****************************** Secondary *************************/
    if (drive->gpt.ignored & MASK_SECONDARY) {
      printf(GPT_FMT,
             (uint64_t)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS),
             (uint64_t)GPT_HEADER_SECTORS, "IGNORED", "Sec GPT header");
    } else {
      GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
      printf(GPT_FMT, (uint64_t)secondary_header->entries_lba,
             (uint64_t)CalculateEntriesSectors(secondary_header,
                         drive->gpt.sector_bytes),
             drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
             "Sec GPT table");
      /* We show secondary table details if any of following is true.
       *   1. in debug mode.
       *   2. primary table is being ignored
       *   3. only secondary is valid.
       *   4. secondary is not identical to primary.
       */
      if (params->debug || (drive->gpt.ignored & MASK_PRIMARY) ||
          ((drive->gpt.valid_entries & MASK_SECONDARY) &&
           (!(drive->gpt.valid_entries & MASK_PRIMARY) ||
            memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries,
                   secondary_header->number_of_entries *
                   secondary_header->size_of_entry)))) {
        EntriesDetails(drive, SECONDARY, params->numeric);
      }

      if (drive->gpt.valid_headers & MASK_SECONDARY) {
        printf(GPT_FMT,
               (uint64_t)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS),
               (uint64_t)GPT_HEADER_SECTORS, "", "Sec GPT header");
      } else {
        printf(GPT_FMT, (uint64_t)GPT_PMBR_SECTORS,
               (uint64_t)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header");
      }
      /* We show secondary header if any of following is true:
       *   1. in debug mode.
       *   2. primary table is being ignored
       *   3. only secondary is valid.
       *   4. secondary is not synonymous to primary and not ignored.
       */
      if (params->debug || (drive->gpt.ignored & MASK_PRIMARY) ||
          ((drive->gpt.valid_headers & MASK_SECONDARY) &&
           (!(drive->gpt.valid_headers & MASK_PRIMARY) ||
            !IsSynonymous((GptHeader*)drive->gpt.primary_header,
                          (GptHeader*)drive->gpt.secondary_header)) &&
           params->verbose)) {
        GptHeader *header;
        char indent[64];

        require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
        header = (GptHeader*)drive->gpt.secondary_header;
        entries = (GptEntry*)drive->gpt.secondary_entries;
        HeaderDetails(header, entries, indent, params->numeric);
      }
    }
  }

  CheckValid(drive);

  return CGPT_OK;
}

int CgptShow(CgptShowParams *params) {
  struct drive drive;

  if (params == NULL)
    return CGPT_FAILED;

  if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY,
                           params->drive_size))
    return CGPT_FAILED;

  int ret = GptShow(&drive, params);
  DriveClose(&drive, 0);
  return ret;
}
