// 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 <getopt.h>
#include <string.h>

#include "cgpt.h"
#include "vboot_host.h"

extern const char* progname;

static void Usage(void)
{
  printf("\nUsage: %s find [OPTIONS] [DRIVE]\n\n"
         "Find a partition by its UUID or label. With no specified DRIVE\n"
         "it scans all physical drives.\n\n"
         "Options:\n"
         "  -D NUM       Size (in bytes) of the disk where partitions reside\n"
         "                 default 0, meaning partitions and GPT structs are\n"
         "                 both on DRIVE\n"
         "  -t GUID      Search for Partition Type GUID\n"
         "  -u GUID      Search for Partition Unique ID\n"
         "  -l LABEL     Search for Label\n"
         "  -v           Be verbose in displaying matches (repeatable)\n"
         "  -n           Numeric output only\n"
         "  -1           Fail if more than one match is found\n"
         "  -M FILE"
         "      Matching partition data must also contain FILE content\n"
         "  -O NUM"
         "       Byte offset into partition to match content (default 0)\n"
         "\n", progname);
  PrintTypes();
}

// read a file into a buffer, return buffer and update size
static uint8_t *ReadFile(const char *filename, uint64_t *size) {
  FILE *f;
  uint8_t *buf;
  long pos;

  f = fopen(filename, "rb");
  if (!f) {
    return NULL;
  }

  fseek(f, 0, SEEK_END);
  pos = ftell(f);
  if (pos < 0) {
    fclose(f);
    return NULL;
  }
  *size = pos;
  rewind(f);

  buf = malloc(*size);
  if (!buf) {
    fclose(f);
    return NULL;
  }

  if(1 != fread(buf, *size, 1, f)) {
    fclose(f);
    free(buf);
    return NULL;
  }

  fclose(f);
  return buf;
}

int cmd_find(int argc, char *argv[]) {

  CgptFindParams params;
  memset(&params, 0, sizeof(params));

  int i;
  int errorcnt = 0;
  char *e = 0;
  int c;

  opterr = 0;                     // quiet, you
  while ((c=getopt(argc, argv, ":hv1nt:u:l:M:O:D:")) != -1)
  {
    switch (c)
    {
    case 'D':
      params.drive_size = strtoull(optarg, &e, 0);
      errorcnt += check_int_parse(c, e);
      break;
    case 'v':
      params.verbose++;
      break;
    case 'n':
      params.numeric = 1;
      break;
    case '1':
      params.oneonly = 1;
      break;
    case 'l':
      params.set_label = 1;
      params.label = optarg;
      break;
    case 't':
      params.set_type = 1;
      if (CGPT_OK != SupportedType(optarg, &params.type_guid) &&
          CGPT_OK != StrToGuid(optarg, &params.type_guid)) {
        Error("invalid argument to -%c: %s\n", c, optarg);
        errorcnt++;
      }
      break;
    case 'u':
      params.set_unique = 1;
      if (CGPT_OK != StrToGuid(optarg, &params.unique_guid)) {
        Error("invalid argument to -%c: %s\n", c, optarg);
        errorcnt++;
      }
      break;
    case 'M':
      params.matchbuf = ReadFile(optarg, &params.matchlen);
      if (!params.matchbuf || !params.matchlen) {
        Error("Unable to read from %s\n", optarg);
        errorcnt++;
      }
      // Go ahead and allocate space for the comparison too
      params.comparebuf = (uint8_t *)malloc(params.matchlen);
      if (!params.comparebuf) {
        Error("Unable to allocate %" PRIu64 "bytes for comparison buffer\n",
              params.matchlen);
        errorcnt++;
      }
      break;
    case 'O':
      params.matchoffset = strtoull(optarg, &e, 0);
      errorcnt += check_int_parse(c, e);
      break;

    case 'h':
      Usage();
      return CGPT_OK;
    case '?':
      Error("unrecognized option: -%c\n", optopt);
      errorcnt++;
      break;
    case ':':
      Error("missing argument to -%c\n", optopt);
      errorcnt++;
      break;
    default:
      errorcnt++;
      break;
    }
  }
  if (!params.set_unique && !params.set_type && !params.set_label) {
    Error("You must specify at least one of -t, -u, or -l\n");
    errorcnt++;
  }
  if (errorcnt)
  {
    Usage();
    return CGPT_FAILED;
  }

  if (optind < argc) {
    for (i=optind; i<argc; i++) {
      params.drive_name = argv[i];
      CgptFind(&params);
      }
  } else {
      CgptFind(&params);
  }

  if (params.oneonly && params.hits != 1) {
    return CGPT_FAILED;
  }

  if (params.match_partnum) {
    return CGPT_OK;
  }

  return CGPT_FAILED;
}
