/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sysexits.h>

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <hardware/hardware.h>
#include <hardware/boot_control.h>

static void usage(FILE* where, int argc, char* argv[])
{
    fprintf(where,
            "%s - command-line wrapper for the boot_control HAL.\n"
            "\n"
            "Usage:\n"
            "  %s COMMAND\n"
            "\n"
            "Commands:\n"
            "  %s hal-info                       - Show info about boot_control HAL used.\n"
            "  %s get-number-slots               - Prints number of slots.\n"
            "  %s get-current-slot               - Prints currently running SLOT.\n"
            "  %s mark-boot-successful           - Mark current slot as GOOD.\n"
            "  %s set-active-boot-slot SLOT      - On next boot, load and execute SLOT.\n"
            "  %s set-slot-as-unbootable SLOT    - Mark SLOT as invalid.\n"
            "  %s is-slot-bootable SLOT          - Returns 0 only if SLOT is bootable.\n"
            "  %s is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n"
            "  %s get-suffix SLOT                - Prints suffix for SLOT.\n"
            "\n"
            "SLOT parameter is the zero-based slot-number.\n",
            argv[0], argv[0], argv[0], argv[0], argv[0], argv[0],
            argv[0], argv[0], argv[0], argv[0], argv[0]);
}

static int do_hal_info(const hw_module_t *hw_module)
{
    fprintf(stdout,
            "HAL name:            %s\n"
            "HAL author:          %s\n"
            "HAL module version:  %d.%d\n",
            hw_module->name,
            hw_module->author,
            hw_module->module_api_version>>8,
            hw_module->module_api_version&0xff);
    return EX_OK;
}

static int do_get_number_slots(boot_control_module_t *module)
{
    int num_slots = module->getNumberSlots(module);
    fprintf(stdout, "%d\n", num_slots);
    return EX_OK;
}

static int do_get_current_slot(boot_control_module_t *module)
{
    int cur_slot = module->getCurrentSlot(module);
    fprintf(stdout, "%d\n", cur_slot);
    return EX_OK;
}

static int do_mark_boot_successful(boot_control_module_t *module)
{
    int ret = module->markBootSuccessful(module);
    if (ret == 0)
        return EX_OK;
    fprintf(stderr, "Error marking as having booted successfully: %s\n",
            strerror(-ret));
    return EX_SOFTWARE;
}

static int do_set_active_boot_slot(boot_control_module_t *module,
                                   int slot_number)
{
    int ret = module->setActiveBootSlot(module, slot_number);
    if (ret == 0)
        return EX_OK;
    fprintf(stderr, "Error setting active boot slot: %s\n", strerror(-ret));
    return EX_SOFTWARE;
}

static int do_set_slot_as_unbootable(boot_control_module_t *module,
                                     int slot_number)
{
    int ret = module->setSlotAsUnbootable(module, slot_number);
    if (ret == 0)
        return EX_OK;
    fprintf(stderr, "Error setting slot as unbootable: %s\n", strerror(-ret));
    return EX_SOFTWARE;
}


static int do_is_slot_bootable(boot_control_module_t *module, int slot_number)
{
    int ret = module->isSlotBootable(module, slot_number);
    if (ret == 0) {
        return EX_SOFTWARE;
    } else if (ret < 0) {
        fprintf(stderr, "Error calling isSlotBootable(): %s\n",
                strerror(-ret));
        return EX_SOFTWARE;
    }
    return EX_OK;
}


static int do_get_suffix(boot_control_module_t *module, int slot_number)
{
    const char* suffix = module->getSuffix(module, slot_number);
    fprintf(stdout, "%s\n", suffix);
    return EX_OK;
}

static int do_is_slot_marked_successful(boot_control_module_t *module,
                                        int slot_number)
{
    if (module->isSlotMarkedSuccessful == NULL) {
        fprintf(stderr, "isSlotMarkedSuccessful() is not implemented by HAL.\n");
        return EX_UNAVAILABLE;
    }
    int ret = module->isSlotMarkedSuccessful(module, slot_number);
    if (ret == 0) {
        return EX_SOFTWARE;
    } else if (ret < 0) {
        fprintf(stderr, "Error calling isSlotMarkedSuccessful(): %s\n",
                strerror(-ret));
        return EX_SOFTWARE;
    }
    return EX_OK;
}

static int parse_slot(int pos, int argc, char *argv[])
{
    if (pos > argc - 1) {
        usage(stderr, argc, argv);
        exit(EX_USAGE);
        return -1;
    }
    errno = 0;
    long int ret = strtol(argv[pos], NULL, 10);
    if (errno != 0 || ret > INT_MAX || ret < 0) {
        usage(stderr, argc, argv);
        exit(EX_USAGE);
        return -1;
    }
    return (int)ret;
}

int main(int argc, char *argv[])
{
    const hw_module_t *hw_module;
    boot_control_module_t *module;
    int ret;

    if (argc < 2) {
        usage(stderr, argc, argv);
        return EX_USAGE;
    }

    ret = hw_get_module("bootctrl", &hw_module);
    if (ret != 0) {
        fprintf(stderr, "Error getting bootctrl module.\n");
        return EX_SOFTWARE;
    }
    module = (boot_control_module_t*) hw_module;
    module->init(module);

    if (strcmp(argv[1], "hal-info") == 0) {
        return do_hal_info(hw_module);
    } else if (strcmp(argv[1], "get-number-slots") == 0) {
        return do_get_number_slots(module);
    } else if (strcmp(argv[1], "get-current-slot") == 0) {
        return do_get_current_slot(module);
    } else if (strcmp(argv[1], "mark-boot-successful") == 0) {
        return do_mark_boot_successful(module);
    } else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
        return do_set_active_boot_slot(module, parse_slot(2, argc, argv));
    } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) {
        return do_set_slot_as_unbootable(module, parse_slot(2, argc, argv));
    } else if (strcmp(argv[1], "is-slot-bootable") == 0) {
        return do_is_slot_bootable(module, parse_slot(2, argc, argv));
    } else if (strcmp(argv[1], "get-suffix") == 0) {
        return do_get_suffix(module, parse_slot(2, argc, argv));
    } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) {
        return do_is_slot_marked_successful(module, parse_slot(2, argc, argv));
    } else {
        usage(stderr, argc, argv);
        return EX_USAGE;
    }

    return 0;
}
