/* Copyright (c) 2010-2011 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 "cgptlib.h"
#include "cgptlib_internal.h"
#include "crc32.h"
#include "gpt.h"
#include "utility.h"

int GptInit(GptData *gpt) {
  int retval;

  gpt->modified = 0;
  gpt->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND;
  gpt->current_priority = 999;

  retval = GptSanityCheck(gpt);
  if (GPT_SUCCESS != retval) {
    VBDEBUG(("GptInit() failed sanity check\n"));
    return retval;
  }

  GptRepair(gpt);
  return GPT_SUCCESS;
}


int GptNextKernelEntry(GptData* gpt, uint64_t* start_sector, uint64_t* size) {
  GptHeader* header = (GptHeader*)gpt->primary_header;
  GptEntry* entries = (GptEntry*)gpt->primary_entries;
  GptEntry* e;
  int new_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND;
  int new_prio = 0;
  uint32_t i;

  /* If we already found a kernel, continue the scan at the current
   * kernel's prioity, in case there is another kernel with the same
   * priority. */
  if (gpt->current_kernel != CGPT_KERNEL_ENTRY_NOT_FOUND) {
    for (i = gpt->current_kernel + 1; i < header->number_of_entries; i++) {
      e = entries + i;
      if (!IsKernelEntry(e))
        continue;
      VBDEBUG(("GptNextKernelEntry looking at same prio partition %d\n", i));
      VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n",
               GetEntrySuccessful(e), GetEntryTries(e), GetEntryPriority(e)));
      if (!(GetEntrySuccessful(e) || GetEntryTries(e)))
        continue;
      if (GetEntryPriority(e) == gpt->current_priority) {
        gpt->current_kernel = i;
        *start_sector = e->starting_lba;
        *size = e->ending_lba - e->starting_lba + 1;
        VBDEBUG(("GptNextKernelEntry likes that one\n"));
        return GPT_SUCCESS;
      }
    }
  }

  /* We're still here, so scan for the remaining kernel with the
   * highest priority less than the previous attempt. */
  for (i = 0, e = entries; i < header->number_of_entries; i++, e++) {
    int current_prio = GetEntryPriority(e);
    if (!IsKernelEntry(e))
      continue;
    VBDEBUG(("GptNextKernelEntry looking at new prio partition %d\n", i));
    VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n",
             GetEntrySuccessful(e), GetEntryTries(e), GetEntryPriority(e)));
    if (!(GetEntrySuccessful(e) || GetEntryTries(e)))
      continue;
    if (current_prio >= gpt->current_priority)
      continue;  /* Already returned this kernel in a previous call */
    if (current_prio > new_prio) {
      new_kernel = i;
      new_prio = current_prio;
    }
  }

  /* Save what we found.  Note that if we didn't find a new kernel,
   * new_prio will still be -1, so future calls to this function will
   * also fail. */
  gpt->current_kernel = new_kernel;
  gpt->current_priority = new_prio;

  if (CGPT_KERNEL_ENTRY_NOT_FOUND == new_kernel) {
    VBDEBUG(("GptNextKernelEntry no more kernels\n"));
    return GPT_ERROR_NO_VALID_KERNEL;
  }

  VBDEBUG(("GptNextKernelEntry likes that one\n"));
  e = entries + new_kernel;
  *start_sector = e->starting_lba;
  *size = e->ending_lba - e->starting_lba + 1;
  return GPT_SUCCESS;
}


int GptUpdateKernelEntry(GptData* gpt, uint32_t update_type) {
  GptHeader* header = (GptHeader*)gpt->primary_header;
  GptEntry* entries = (GptEntry*)gpt->primary_entries;
  GptEntry* e = entries + gpt->current_kernel;
  uint16_t previous_attr = e->attrs.fields.gpt_att;

  if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND)
    return GPT_ERROR_INVALID_UPDATE_TYPE;
  if (!IsKernelEntry(e))
    return GPT_ERROR_INVALID_UPDATE_TYPE;

  switch (update_type) {
    case GPT_UPDATE_ENTRY_TRY: {
      /* Used up a try */
      int tries;
      if (GetEntrySuccessful(e))
        return GPT_SUCCESS;  /* Successfully booted this partition, so
                              * tries field is ignored. */
      tries = GetEntryTries(e);
      if (tries > 1) {
        /* Still have tries left */
        SetEntryTries(e, tries - 1);
        break;
      }
      /* Out of tries, so drop through and mark partition bad. */
    }
    case GPT_UPDATE_ENTRY_BAD: {
      /* Giving up on this partition entirely. */
      if (!GetEntrySuccessful(e)) {
        /* Only clear tries and priority if the successful bit is not set. */
        e->attrs.fields.gpt_att = previous_attr & ~(
            CGPT_ATTRIBUTE_TRIES_MASK |
            CGPT_ATTRIBUTE_PRIORITY_MASK);
      }
      break;
    }
    default:
      return GPT_ERROR_INVALID_UPDATE_TYPE;
  }

  /* If no change to attributes, we're done */
  if (e->attrs.fields.gpt_att == previous_attr)
    return GPT_SUCCESS;

  /* Update the CRCs */
  header->entries_crc32 = Crc32((const uint8_t *)entries,
                                header->size_of_entry *
                                header->number_of_entries);
  header->header_crc32 = HeaderCrc(header);
  gpt->modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;

  /* Use the repair function to update the other copy of the GPT.
   * This is a tad inefficient, but is much faster than the disk I/O
   * to update the GPT on disk so it doesn't matter. */
  gpt->valid_headers = MASK_PRIMARY;
  gpt->valid_entries = MASK_PRIMARY;
  GptRepair(gpt);

  return GPT_SUCCESS;
}
