/* 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 (blocks)\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("%#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 (params->debug || params->verbose) {
      printf("Drive details:\n");
      printf("    Total Size (bytes): %" PRIu64 "\n", drive->size);
      printf("    LBA Size (bytes): %d\n", drive->gpt.sector_bytes);
      if (drive->gpt.flags & GPT_FLAG_EXTERNAL) {
        printf("    Drive (where GPT lives) Size (blocks): %" PRIu64 "\n",
               drive->gpt.gpt_drive_sectors);
        printf("    Drive (where partitions live) Size (blocks): %" PRIu64 "\n",
               drive->gpt.streaming_drive_sectors);
      } else {
        // We know gpt_drive_sectors == streaming_drive_sectors here.
        printf("    Drive Size (blocks): %" PRIu64 "\n",
               drive->gpt.gpt_drive_sectors);
      }
      printf("\n");
    }

    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;
}
