/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "avb_ab_flow.h"

bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest) {
  /* Ensure magic is correct. */
  if (avb_safe_memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
    avb_error("Magic is incorrect.\n");
    return false;
  }

  avb_memcpy(dest, src, sizeof(AvbABData));
  dest->crc32 = avb_be32toh(dest->crc32);

  /* Ensure we don't attempt to access any fields if the major version
   * is not supported.
   */
  if (dest->version_major > AVB_AB_MAJOR_VERSION) {
    avb_error("No support for given major version.\n");
    return false;
  }

  /* Bail if CRC32 doesn't match. */
  if (dest->crc32 !=
      avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
    avb_error("CRC32 does not match.\n");
    return false;
  }

  return true;
}

void avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
                                         AvbABData* dest) {
  avb_memcpy(dest, src, sizeof(AvbABData));
  dest->crc32 = avb_htobe32(
      avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t)));
}

void avb_ab_data_init(AvbABData* data) {
  avb_memset(data, '\0', sizeof(AvbABData));
  avb_memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  data->version_major = AVB_AB_MAJOR_VERSION;
  data->version_minor = AVB_AB_MINOR_VERSION;
  data->slots[0].priority = AVB_AB_MAX_PRIORITY;
  data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  data->slots[0].successful_boot = 0;
  data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
  data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  data->slots[1].successful_boot = 0;
}

/* The AvbABData struct is stored 2048 bytes into the 'misc' partition
 * following the 'struct bootloader_message' field. The struct is
 * compatible with the guidelines in bootable/recovery/bootloader.h -
 * e.g. it is stored in the |slot_suffix| field, starts with a
 * NUL-byte, and is 32 bytes long.
 */
#define AB_METADATA_MISC_PARTITION_OFFSET 2048

AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data) {
  AvbOps* ops = ab_ops->ops;
  AvbABData serialized;
  AvbIOResult io_ret;
  size_t num_bytes_read;

  io_ret = ops->read_from_partition(ops,
                                    "misc",
                                    AB_METADATA_MISC_PARTITION_OFFSET,
                                    sizeof(AvbABData),
                                    &serialized,
                                    &num_bytes_read);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    return AVB_IO_RESULT_ERROR_OOM;
  } else if (io_ret != AVB_IO_RESULT_OK ||
             num_bytes_read != sizeof(AvbABData)) {
    avb_error("Error reading A/B metadata.\n");
    return AVB_IO_RESULT_ERROR_IO;
  }

  if (!avb_ab_data_verify_and_byteswap(&serialized, data)) {
    avb_error(
        "Error validating A/B metadata from disk. "
        "Resetting and writing new A/B metadata to disk.\n");
    avb_ab_data_init(data);
    return avb_ab_data_write(ab_ops, data);
  }

  return AVB_IO_RESULT_OK;
}

AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data) {
  AvbOps* ops = ab_ops->ops;
  AvbABData serialized;
  AvbIOResult io_ret;

  avb_ab_data_update_crc_and_byteswap(data, &serialized);
  io_ret = ops->write_to_partition(ops,
                                   "misc",
                                   AB_METADATA_MISC_PARTITION_OFFSET,
                                   sizeof(AvbABData),
                                   &serialized);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    return AVB_IO_RESULT_ERROR_OOM;
  } else if (io_ret != AVB_IO_RESULT_OK) {
    avb_error("Error writing A/B metadata.\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static bool slot_is_bootable(AvbABSlotData* slot) {
  return slot->priority > 0 &&
         (slot->successful_boot || (slot->tries_remaining > 0));
}

static void slot_set_unbootable(AvbABSlotData* slot) {
  slot->priority = 0;
  slot->tries_remaining = 0;
  slot->successful_boot = 0;
}

/* Ensure all unbootable and/or illegal states are marked as the
 * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
 * and successful_boot=0.
 */
static void slot_normalize(AvbABSlotData* slot) {
  if (slot->priority > 0) {
    if (slot->tries_remaining == 0 && !slot->successful_boot) {
      /* We've exhausted all tries -> unbootable. */
      slot_set_unbootable(slot);
    }
    if (slot->tries_remaining > 0 && slot->successful_boot) {
      /* Illegal state - avb_ab_mark_slot_successful() will clear
       * tries_remaining when setting successful_boot.
       */
      slot_set_unbootable(slot);
    }
  } else {
    slot_set_unbootable(slot);
  }
}

static const char* slot_suffixes[2] = {"_a", "_b"};

/* Helper function to load metadata - returns AVB_IO_RESULT_OK on
 * success, error code otherwise.
 */
static AvbIOResult load_metadata(AvbABOps* ab_ops,
                                 AvbABData* ab_data,
                                 AvbABData* ab_data_orig) {
  AvbIOResult io_ret;

  io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
  if (io_ret != AVB_IO_RESULT_OK) {
    avb_error("I/O error while loading A/B metadata.\n");
    return io_ret;
  }
  *ab_data_orig = *ab_data;

  /* Ensure data is normalized, e.g. illegal states will be marked as
   * unbootable and all unbootable states are represented with
   * (priority=0, tries_remaining=0, successful_boot=0).
   */
  slot_normalize(&ab_data->slots[0]);
  slot_normalize(&ab_data->slots[1]);
  return AVB_IO_RESULT_OK;
}

/* Writes A/B metadata to disk only if it has changed - returns
 * AVB_IO_RESULT_OK on success, error code otherwise.
 */
static AvbIOResult save_metadata_if_changed(AvbABOps* ab_ops,
                                            AvbABData* ab_data,
                                            AvbABData* ab_data_orig) {
  if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
    avb_debug("Writing A/B metadata to disk.\n");
    return ab_ops->write_ab_metadata(ab_ops, ab_data);
  }
  return AVB_IO_RESULT_OK;
}

AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
                            const char* const* requested_partitions,
                            AvbSlotVerifyFlags flags,
                            AvbHashtreeErrorMode hashtree_error_mode,
                            AvbSlotVerifyData** out_data) {
  AvbOps* ops = ab_ops->ops;
  AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
  AvbSlotVerifyData* data = NULL;
  AvbABFlowResult ret;
  AvbABData ab_data, ab_data_orig;
  size_t slot_index_to_boot, n;
  AvbIOResult io_ret;
  bool saw_and_allowed_verification_error = false;

  io_ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    goto out;
  } else if (io_ret != AVB_IO_RESULT_OK) {
    ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    goto out;
  }

  /* Validate all bootable slots. */
  for (n = 0; n < 2; n++) {
    if (slot_is_bootable(&ab_data.slots[n])) {
      AvbSlotVerifyResult verify_result;
      bool set_slot_unbootable = false;

      verify_result = avb_slot_verify(ops,
                                      requested_partitions,
                                      slot_suffixes[n],
                                      flags,
                                      hashtree_error_mode,
                                      &slot_data[n]);
      switch (verify_result) {
        case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
          ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
          goto out;

        case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
          ret = AVB_AB_FLOW_RESULT_ERROR_IO;
          goto out;

        case AVB_SLOT_VERIFY_RESULT_OK:
          break;

        case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
        case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
          /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
           * these mean game over.
           */
          set_slot_unbootable = true;
          break;

        /* explicit fallthrough. */
        case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
        case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
        case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
          if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
            /* Do nothing since we allow this. */
            avb_debugv("Allowing slot ",
                       slot_suffixes[n],
                       " which verified "
                       "with result ",
                       avb_slot_verify_result_to_string(verify_result),
                       " because "
                       "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
                       "is set.\n",
                       NULL);
            saw_and_allowed_verification_error = true;
          } else {
            set_slot_unbootable = true;
          }
          break;

        case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
          ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
          goto out;
          /* Do not add a 'default:' case here because of -Wswitch. */
      }

      if (set_slot_unbootable) {
        avb_errorv("Error verifying slot ",
                   slot_suffixes[n],
                   " with result ",
                   avb_slot_verify_result_to_string(verify_result),
                   " - setting unbootable.\n",
                   NULL);
        slot_set_unbootable(&ab_data.slots[n]);
      }
    }
  }

  if (slot_is_bootable(&ab_data.slots[0]) &&
      slot_is_bootable(&ab_data.slots[1])) {
    if (ab_data.slots[1].priority > ab_data.slots[0].priority) {
      slot_index_to_boot = 1;
    } else {
      slot_index_to_boot = 0;
    }
  } else if (slot_is_bootable(&ab_data.slots[0])) {
    slot_index_to_boot = 0;
  } else if (slot_is_bootable(&ab_data.slots[1])) {
    slot_index_to_boot = 1;
  } else {
    /* No bootable slots! */
    avb_error("No bootable slots found.\n");
    ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
    goto out;
  }

  /* Update stored rollback index such that the stored rollback index
   * is the largest value supporting all currently bootable slots. Do
   * this for every rollback index location.
   */
  for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    uint64_t rollback_index_value = 0;

    if (slot_data[0] != NULL && slot_data[1] != NULL) {
      uint64_t a_rollback_index = slot_data[0]->rollback_indexes[n];
      uint64_t b_rollback_index = slot_data[1]->rollback_indexes[n];
      rollback_index_value =
          (a_rollback_index < b_rollback_index ? a_rollback_index
                                               : b_rollback_index);
    } else if (slot_data[0] != NULL) {
      rollback_index_value = slot_data[0]->rollback_indexes[n];
    } else if (slot_data[1] != NULL) {
      rollback_index_value = slot_data[1]->rollback_indexes[n];
    }

    if (rollback_index_value != 0) {
      uint64_t current_rollback_index_value;
      io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
      if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
        ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
        goto out;
      } else if (io_ret != AVB_IO_RESULT_OK) {
        avb_error("Error getting rollback index for slot.\n");
        ret = AVB_AB_FLOW_RESULT_ERROR_IO;
        goto out;
      }
      if (current_rollback_index_value != rollback_index_value) {
        io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
        if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
          ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
          goto out;
        } else if (io_ret != AVB_IO_RESULT_OK) {
          avb_error("Error setting stored rollback index.\n");
          ret = AVB_AB_FLOW_RESULT_ERROR_IO;
          goto out;
        }
      }
    }
  }

  /* Finally, select this slot. */
  avb_assert(slot_data[slot_index_to_boot] != NULL);
  data = slot_data[slot_index_to_boot];
  slot_data[slot_index_to_boot] = NULL;
  if (saw_and_allowed_verification_error) {
    avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
    ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
  } else {
    ret = AVB_AB_FLOW_RESULT_OK;
  }

  /* ... and decrement tries remaining, if applicable. */
  if (!ab_data.slots[slot_index_to_boot].successful_boot &&
      ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
    ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
  }

out:
  io_ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret != AVB_IO_RESULT_OK) {
    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
      ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    } else {
      ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    }
    if (data != NULL) {
      avb_slot_verify_data_free(data);
      data = NULL;
    }
  }

  for (n = 0; n < 2; n++) {
    if (slot_data[n] != NULL) {
      avb_slot_verify_data_free(slot_data[n]);
    }
  }

  if (out_data != NULL) {
    *out_data = data;
  } else {
    if (data != NULL) {
      avb_slot_verify_data_free(data);
    }
  }

  return ret;
}

AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
                            const char* const* requested_partitions,
                            AvbSlotVerifyFlags flags,
                            AvbHashtreeErrorMode hashtree_error_mode,
                            AvbSlotVerifyData** out_data) {
  AvbOps* ops = ab_ops->ops;
  AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
  AvbSlotVerifyData* data = NULL;
  AvbABFlowResult ret;
  AvbABData ab_data, ab_data_orig;
  size_t slot_index_to_boot, n;
  AvbIOResult io_ret;
  bool saw_and_allowed_verification_error = false;
  size_t target_slot;
  AvbSlotVerifyResult verify_result;
  bool set_slot_unbootable = false;

  io_ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    goto out;
  } else if (io_ret != AVB_IO_RESULT_OK) {
    ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    goto out;
  }

  slot_index_to_boot = 2;  // Means not 0 or 1
  target_slot = (ab_data.slots[1].priority > ab_data.slots[0].priority? 1 : 0);

  for (n = 0; n < 2; n++) {
    if (!slot_is_bootable(&ab_data.slots[target_slot])) {
      target_slot = (target_slot == 1 ? 0 : 1);
      continue;
    }
    verify_result = avb_slot_verify(ops,
                                      requested_partitions,
                                      slot_suffixes[target_slot],
                                      flags,
                                      hashtree_error_mode,
                                      &slot_data[target_slot]);
    switch (verify_result) {
      case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
        ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
        goto out;

      case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
        ret = AVB_AB_FLOW_RESULT_ERROR_IO;
        goto out;

      case AVB_SLOT_VERIFY_RESULT_OK:
	slot_index_to_boot = target_slot;
	n = 2;
        break;

      case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
      case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
          /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
           * these mean game over.
           */
        set_slot_unbootable = true;
        break;

      /* explicit fallthrough. */
      case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
      case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
      case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
        if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
          /* Do nothing since we allow this. */
          avb_debugv("Allowing slot ",
                     slot_suffixes[target_slot],
                     " which verified "
                     "with result ",
                     avb_slot_verify_result_to_string(verify_result),
                     " because "
                     "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
                     "is set.\n",
                     NULL);
          saw_and_allowed_verification_error = true;
	  slot_index_to_boot = target_slot;
	  n = 2;
        } else {
          set_slot_unbootable = true;
        }
        break;

      case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
        ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
        goto out;
        /* Do not add a 'default:' case here because of -Wswitch. */
    }

    if (set_slot_unbootable) {
      avb_errorv("Error verifying slot ",
                 slot_suffixes[target_slot],
                 " with result ",
                 avb_slot_verify_result_to_string(verify_result),
                 " - setting unbootable.\n",
                 NULL);
      slot_set_unbootable(&ab_data.slots[target_slot]);
      set_slot_unbootable = false;
    }
    /* switch to another slot */
    target_slot = (target_slot == 1 ? 0 : 1);
  }

  if (slot_index_to_boot == 2) {
    /* No bootable slots! */
    avb_error("No bootable slots found.\n");
    ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
    goto out;
  }

  /* Update stored rollback index such that the stored rollback index
   * is the largest value supporting all currently bootable slots. Do
   * this for every rollback index location.
   */
  for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    uint64_t rollback_index_value = 0;

    if (slot_data[0] != NULL && slot_data[1] != NULL) {
      uint64_t a_rollback_index = slot_data[0]->rollback_indexes[n];
      uint64_t b_rollback_index = slot_data[1]->rollback_indexes[n];
      rollback_index_value =
          (a_rollback_index < b_rollback_index ? a_rollback_index
                                               : b_rollback_index);
    } else if (slot_data[0] != NULL) {
      rollback_index_value = slot_data[0]->rollback_indexes[n];
    } else if (slot_data[1] != NULL) {
      rollback_index_value = slot_data[1]->rollback_indexes[n];
    }

    if (rollback_index_value != 0) {
      uint64_t current_rollback_index_value;
      io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
      if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
        ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
        goto out;
      } else if (io_ret != AVB_IO_RESULT_OK) {
        avb_error("Error getting rollback index for slot.\n");
        ret = AVB_AB_FLOW_RESULT_ERROR_IO;
        goto out;
      }
      if (current_rollback_index_value != rollback_index_value) {
        io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
        if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
          ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
          goto out;
        } else if (io_ret != AVB_IO_RESULT_OK) {
          avb_error("Error setting stored rollback index.\n");
          ret = AVB_AB_FLOW_RESULT_ERROR_IO;
          goto out;
        }
      }
    }
  }

  /* Finally, select this slot. */
  avb_assert(slot_data[slot_index_to_boot] != NULL);
  data = slot_data[slot_index_to_boot];
  slot_data[slot_index_to_boot] = NULL;
  if (saw_and_allowed_verification_error) {
    avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
    ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
  } else {
    ret = AVB_AB_FLOW_RESULT_OK;
  }

  /* ... and decrement tries remaining, if applicable. */
  if (!ab_data.slots[slot_index_to_boot].successful_boot &&
      ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
    ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
  }

out:
  io_ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret != AVB_IO_RESULT_OK) {
    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
      ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    } else {
      ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    }
    if (data != NULL) {
      avb_slot_verify_data_free(data);
      data = NULL;
    }
  }

  for (n = 0; n < 2; n++) {
    if (slot_data[n] != NULL) {
      avb_slot_verify_data_free(slot_data[n]);
    }
  }

  if (out_data != NULL) {
    *out_data = data;
  } else {
    if (data != NULL) {
      avb_slot_verify_data_free(data);
    }
  }

  return ret;
}

AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops,
                                    unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  unsigned int other_slot_number;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  /* Make requested slot top priority, unsuccessful, and with max tries. */
  ab_data.slots[slot_number].priority = AVB_AB_MAX_PRIORITY;
  ab_data.slots[slot_number].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  ab_data.slots[slot_number].successful_boot = 0;

  /* Ensure other slot doesn't have as high a priority. */
  other_slot_number = 1 - slot_number;
  if (ab_data.slots[other_slot_number].priority == AVB_AB_MAX_PRIORITY) {
    ab_data.slots[other_slot_number].priority = AVB_AB_MAX_PRIORITY - 1;
  }

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
                                        unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  slot_set_unbootable(&ab_data.slots[slot_number]);

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
                                        unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  if (!slot_is_bootable(&ab_data.slots[slot_number])) {
    avb_error("Cannot mark unbootable slot as successful.\n");
    ret = AVB_IO_RESULT_OK;
    goto out;
  }

  ab_data.slots[slot_number].tries_remaining = 0;
  ab_data.slots[slot_number].successful_boot = 1;

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

const char* avb_ab_flow_result_to_string(AvbABFlowResult result) {
  const char* ret = NULL;

  switch (result) {
    case AVB_AB_FLOW_RESULT_OK:
      ret = "OK";
      break;

    case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
      ret = "OK_WITH_VERIFICATION_ERROR";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_OOM:
      ret = "ERROR_OOM";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_IO:
      ret = "ERROR_IO";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
      ret = "ERROR_NO_BOOTABLE_SLOTS";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
      ret = "ERROR_INVALID_ARGUMENT";
      break;
      /* Do not add a 'default:' case here because of -Wswitch. */
  }

  if (ret == NULL) {
    avb_error("Unknown AvbABFlowResult value.\n");
    ret = "(unknown)";
  }

  return ret;
}
