// 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.

#include "cgpt.h"

#define __STDC_FORMAT_MACROS

#include <string.h>

#include "cgptlib_internal.h"
#include "cgpt_params.h"

static void Usage(void) {
  printf("\nUsage: %s show [OPTIONS] DRIVE\n\n"
         "Display the GPT table\n\n"
         "Options:\n"
         "  -n           Numeric output only\n"
         "  -v           Verbose output\n"
         "  -q           Quick output\n"
         "  -i NUM       Show specified partition only - pick one of:\n"
         "               -b  beginning sector\n"
         "               -s  partition size\n"
         "               -t  type guid\n"
         "               -u  unique guid\n"
         "               -l  label\n"
         "               -S  Successful flag\n"
         "               -T  Tries flag\n"
         "               -P  Priority flag\n"
         "               -A  raw 64-bit attribute value\n"
         "\n", progname);
}


/* 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      "%10s%10s%8s  %s\n"
#define GPT_FMT        "%10d%10d%8s  %s\n"
#define GPT_MORE       "%10s%10s%8s  ", "", "", ""
#define PARTITION_FMT  "%10d%10d%8d  %s\n"
#define PARTITION_MORE "%10s%10s%8s  %s%s\n", "", "", ""

static void HeaderDetails(GptHeader *header, const char *indent, int raw) {
  int i;

  printf("%sSig: ", indent);
  if (!raw) {
    printf("[");
    for (i = 0; i < sizeof(header->signature); ++i)
      printf("%c", header->signature[i]);
    printf("]");
  } else {
    char buf[BUFFER_SIZE(sizeof(header->signature))];
    RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1);
    printf("%s", buf);
  }
  printf("\n");

  printf("%sRev: 0x%08x\n", indent, header->revision);
  printf("%sSize: %d\n", indent, header->size);
  printf("%sHeader CRC: 0x%08x\n", indent, header->header_crc32);
  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\n", indent, header->entries_crc32);
}

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

  if (!raw) {
    char type[GUID_STRLEN], unique[GUID_STRLEN];

    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, (int)entry->starting_lba,
           (int)(entry->ending_lba - entry->starting_lba + 1),
           index+1, contents);
    if (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);
    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;
      require(snprintf(contents, sizeof(contents),
                       "priority=%d tries=%d successful=%d",
                       priority, tries, successful) < sizeof(contents));
      printf(PARTITION_MORE, "Attr: ", contents);
    }
  } else {
    char type[GUID_STRLEN], unique[GUID_STRLEN];

    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, (int)entry->starting_lba,
           (int)(entry->ending_lba - entry->starting_lba + 1),
           index+1, contents);
    GuidToStr(&entry->type, type, GUID_STRLEN);
    printf(PARTITION_MORE, "Type: ", type);
    GuidToStr(&entry->unique, unique, GUID_STRLEN);
    printf(PARTITION_MORE, "UUID: ", unique);
    require(snprintf(contents, sizeof(contents),
                     "[%x]", entry->attrs.fields.gpt_att) < sizeof(contents));
    printf(PARTITION_MORE, "Attr: ", contents);
  }
}


void EntriesDetails(GptData *gpt, const int secondary, int raw) {
  uint32_t i;

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

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

    EntryDetails(entry, i, raw);
  }
}

int cgpt_get_num_non_empty_partitions(CgptShowParams *params) {
  struct drive drive;
  int gpt_retval;
  int retval;

  if (params == NULL)
    return CGPT_FAILED;

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

  if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
    Error("GptSanityCheck() returned %d: %s\n",
          gpt_retval, GptError(gpt_retval));
    retval = CGPT_FAILED;
    goto done;
  }

  params->num_partitions = 0;
  int numEntries = GetNumberOfEntries(&drive.gpt);
  int i;
  for(i = 0; i < numEntries; i++) {
      GptEntry *entry = GetEntry(&drive.gpt, ANY_VALID, i);
      if (IsZero(&entry->type))
        continue;

      params->num_partitions++;
  }

  retval = CGPT_OK;

done:
  DriveClose(&drive, 0);
  return retval;
}

int cgpt_show(CgptShowParams *params) {
  struct drive drive;
  int gpt_retval;

  if (params == NULL)
    return CGPT_FAILED;

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

  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.gpt)) {
      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':
        printf("%" PRId64 "\n", entry->ending_lba - entry->starting_lba + 1);
        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.gpt, ANY_VALID, index));
        break;
      case 'T':
        printf("%d\n", GetTries(&drive.gpt, ANY_VALID, index));
        break;
      case 'P':
        printf("%d\n", GetPriority(&drive.gpt, 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.gpt); ++i) {
      entry = GetEntry(&drive.gpt, ANY_VALID, i);

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

      if (!params->numeric && CGPT_OK == ResolveType(&entry->type, type)) {
      } else {
        GuidToStr(&entry->type, type, GUID_STRLEN);
      }
      printf(PARTITION_FMT, (int)entry->starting_lba,
             (int)(entry->ending_lba - entry->starting_lba + 1),
             i+1, type);
    }
  } else {                              // show all partitions
    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, 0, GPT_PMBR_SECTOR, "", buf);

    if (drive.gpt.valid_headers & MASK_PRIMARY) {
      printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
             (int)GPT_HEADER_SECTOR, "", "Pri GPT header");
      if (params->verbose) {
        GptHeader *header;
        char indent[64];

        require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
        header = (GptHeader*)drive.gpt.primary_header;
        HeaderDetails(header, indent, params->numeric);
      }
    } else {
      printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
             (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header");
    }

    printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
           (int)GPT_ENTRIES_SECTORS,
           drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
           "Pri GPT table");

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

    printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR -
                          GPT_ENTRIES_SECTORS),
           (int)GPT_ENTRIES_SECTORS,
           drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
           "Sec GPT table");
    /* We show secondary table details if any of following is true.
     *   1. only secondary is valid.
     *   2. secondary is not identical to promary.
     */
    if ((drive.gpt.valid_entries & MASK_SECONDARY) &&
        (!(drive.gpt.valid_entries & MASK_PRIMARY) ||
         memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries,
                TOTAL_ENTRIES_SIZE))) {
      EntriesDetails(&drive.gpt, SECONDARY, params->numeric);
    }

    if (drive.gpt.valid_headers & MASK_SECONDARY)
      printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
             (int)GPT_HEADER_SECTOR, "", "Sec GPT header");
    else
      printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
             (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header");
    /* We show secondary header if any of following is true:
     *   1. only secondary is valid.
     *   2. secondary is not synonymous to primary.
     */
    if ((drive.gpt.valid_headers & MASK_SECONDARY) &&
        (!(drive.gpt.valid_headers & MASK_PRIMARY) ||
         !IsSynonymous((GptHeader*)drive.gpt.primary_header,
                       (GptHeader*)drive.gpt.secondary_header))) {
      if (params->verbose) {
        GptHeader *header;
        char indent[64];

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

  CheckValid(&drive);
  DriveClose(&drive, 0);

  return CGPT_OK;
}
