/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "engine.h"

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <vector>

#include <android-base/stringprintf.h>

#include "constants.h"
#include "transport.h"

enum Op {
    OP_DOWNLOAD,
    OP_COMMAND,
    OP_QUERY,
    OP_NOTICE,
    OP_DOWNLOAD_SPARSE,
    OP_WAIT_FOR_DISCONNECT,
    OP_DOWNLOAD_FD,
    OP_UPLOAD,
};

struct Action {
    Action(Op op, const std::string& cmd) : op(op), cmd(cmd) {}

    Op op;
    std::string cmd;
    std::string msg;

    std::string product;

    void* data = nullptr;
    // The protocol only supports 32-bit sizes, so you'll have to break
    // anything larger into multiple chunks.
    uint32_t size = 0;

    int fd = -1;

    int (*func)(Action& a, int status, const char* resp) = nullptr;

    double start = -1;
};

static std::vector<std::unique_ptr<Action>> action_list;
static fastboot::FastBootDriver* fb = nullptr;

static constexpr char kStatusFormat[] = "%-50s ";

void fb_init(fastboot::FastBootDriver& fbi) {
    fb = &fbi;
    auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); };
    fb->SetInfoCallback(cb);
}

void fb_reinit(Transport* transport) {
    if (Transport* old_transport = fb->set_transport(transport)) {
        delete old_transport;
    }
}

const std::string fb_get_error() {
    return fb->Error();
}

bool fb_getvar(const std::string& key, std::string* value) {
    return !fb->GetVar(key, value);
}

static int cb_default(Action& a, int status, const char* resp) {
    if (status) {
        fprintf(stderr,"FAILED (%s)\n", resp);
    } else {
        double split = now();
        fprintf(stderr, "OKAY [%7.3fs]\n", (split - a.start));
        a.start = split;
    }
    return status;
}

static Action& queue_action(Op op, const std::string& cmd) {
    std::unique_ptr<Action> a{new Action(op, cmd)};
    a->func = cb_default;

    action_list.push_back(std::move(a));
    return *action_list.back();
}

void fb_set_active(const std::string& slot) {
    Action& a = queue_action(OP_COMMAND, FB_CMD_SET_ACTIVE ":" + slot);
    a.msg = "Setting current slot to '" + slot + "'";
}

void fb_queue_erase(const std::string& partition) {
    Action& a = queue_action(OP_COMMAND, FB_CMD_ERASE ":" + partition);
    a.msg = "Erasing '" + partition + "'";
}

void fb_queue_flash_fd(const std::string& partition, int fd, uint32_t sz) {
    Action& a = queue_action(OP_DOWNLOAD_FD, "");
    a.fd = fd;
    a.size = sz;
    a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024);

    Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition);
    b.msg = "Writing '" + partition + "'";
}

void fb_queue_flash(const std::string& partition, void* data, uint32_t sz) {
    Action& a = queue_action(OP_DOWNLOAD, "");
    a.data = data;
    a.size = sz;
    a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024);

    Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition);
    b.msg = "Writing '" + partition + "'";
}

void fb_queue_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz,
                           size_t current, size_t total) {
    Action& a = queue_action(OP_DOWNLOAD_SPARSE, "");
    a.data = s;
    a.size = 0;
    a.msg = android::base::StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(),
                                        current, total, sz / 1024);

    Action& b = queue_action(OP_COMMAND, FB_CMD_FLASH ":" + partition);
    b.msg = android::base::StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current,
                                        total);
}

void fb_queue_create_partition(const std::string& partition, const std::string& size) {
    Action& a = queue_action(OP_COMMAND, FB_CMD_CREATE_PARTITION ":" + partition + ":" + size);
    a.msg = "Creating '" + partition + "'";
}

void fb_queue_delete_partition(const std::string& partition) {
    Action& a = queue_action(OP_COMMAND, FB_CMD_DELETE_PARTITION ":" + partition);
    a.msg = "Deleting '" + partition + "'";
}

void fb_queue_resize_partition(const std::string& partition, const std::string& size) {
    Action& a = queue_action(OP_COMMAND, FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size);
    a.msg = "Resizing '" + partition + "'";
}

static int match(const char* str, const char** value, unsigned count) {
    unsigned n;

    for (n = 0; n < count; n++) {
        const char *val = value[n];
        int len = strlen(val);
        int match;

        if ((len > 1) && (val[len-1] == '*')) {
            len--;
            match = !strncmp(val, str, len);
        } else {
            match = !strcmp(val, str);
        }

        if (match) return 1;
    }

    return 0;
}

static int cb_check(Action& a, int status, const char* resp, int invert) {
    const char** value = reinterpret_cast<const char**>(a.data);
    unsigned count = a.size;
    unsigned n;

    if (status) {
        fprintf(stderr,"FAILED (%s)\n", resp);
        return status;
    }

    if (!a.product.empty()) {
        if (a.product != cur_product) {
            double split = now();
            fprintf(stderr, "IGNORE, product is %s required only for %s [%7.3fs]\n", cur_product,
                    a.product.c_str(), (split - a.start));
            a.start = split;
            return 0;
        }
    }

    int yes = match(resp, value, count);
    if (invert) yes = !yes;

    if (yes) {
        double split = now();
        fprintf(stderr, "OKAY [%7.3fs]\n", (split - a.start));
        a.start = split;
        return 0;
    }

    fprintf(stderr, "FAILED\n\n");
    fprintf(stderr, "Device %s is '%s'.\n", a.cmd.c_str() + 7, resp);
    fprintf(stderr, "Update %s '%s'", invert ? "rejects" : "requires", value[0]);
    for (n = 1; n < count; n++) {
        fprintf(stderr, " or '%s'", value[n]);
    }
    fprintf(stderr, ".\n\n");
    return -1;
}

static int cb_require(Action& a, int status, const char* resp) {
    return cb_check(a, status, resp, 0);
}

static int cb_reject(Action& a, int status, const char* resp) {
    return cb_check(a, status, resp, 1);
}

void fb_queue_require(const std::string& product, const std::string& var, bool invert,
                      size_t nvalues, const char** values) {
    Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var);
    a.product = product;
    a.data = values;
    a.size = nvalues;
    a.msg = "Checking " + var;
    a.func = invert ? cb_reject : cb_require;
    if (a.data == nullptr) die("out of memory");
}

static int cb_display(Action& a, int status, const char* resp) {
    if (status) {
        fprintf(stderr, "%s FAILED (%s)\n", a.cmd.c_str(), resp);
        return status;
    }
    fprintf(stderr, "%s: %s\n", static_cast<const char*>(a.data), resp);
    free(static_cast<char*>(a.data));
    return 0;
}

void fb_queue_display(const std::string& label, const std::string& var) {
    Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var);
    a.data = xstrdup(label.c_str());
    a.func = cb_display;
}

static int cb_save(Action& a, int status, const char* resp) {
    if (status) {
        fprintf(stderr, "%s FAILED (%s)\n", a.cmd.c_str(), resp);
        return status;
    }
    strncpy(reinterpret_cast<char*>(a.data), resp, a.size);
    return 0;
}

void fb_queue_query_save(const std::string& var, char* dest, uint32_t dest_size) {
    Action& a = queue_action(OP_QUERY, FB_CMD_GETVAR ":" + var);
    a.data = dest;
    a.size = dest_size;
    a.func = cb_save;
}

static int cb_do_nothing(Action&, int, const char*) {
    fprintf(stderr, "\n");
    return 0;
}

void fb_queue_reboot() {
    Action& a = queue_action(OP_COMMAND, FB_CMD_REBOOT);
    a.func = cb_do_nothing;
    a.msg = "Rebooting";
}

void fb_queue_command(const std::string& cmd, const std::string& msg) {
    Action& a = queue_action(OP_COMMAND, cmd);
    a.msg = msg;
}

void fb_queue_download(const std::string& name, void* data, uint32_t size) {
    Action& a = queue_action(OP_DOWNLOAD, "");
    a.data = data;
    a.size = size;
    a.msg = "Downloading '" + name + "'";
}

void fb_queue_download_fd(const std::string& name, int fd, uint32_t sz) {
    Action& a = queue_action(OP_DOWNLOAD_FD, "");
    a.fd = fd;
    a.size = sz;
    a.msg = android::base::StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024);
}

void fb_queue_upload(const std::string& outfile) {
    Action& a = queue_action(OP_UPLOAD, "");
    a.data = xstrdup(outfile.c_str());
    a.msg = "Uploading '" + outfile + "'";
}

void fb_queue_notice(const std::string& notice) {
    Action& a = queue_action(OP_NOTICE, "");
    a.msg = notice;
}

void fb_queue_wait_for_disconnect() {
    queue_action(OP_WAIT_FOR_DISCONNECT, "");
}

int64_t fb_execute_queue() {
    int64_t status = 0;
    for (auto& a : action_list) {
        a->start = now();
        if (!a->msg.empty()) {
            fprintf(stderr, kStatusFormat, a->msg.c_str());
            verbose("\n");
        }
        if (a->op == OP_DOWNLOAD) {
            char* cbuf = static_cast<char*>(a->data);
            status = fb->Download(cbuf, a->size);
            status = a->func(*a, status, status ? fb_get_error().c_str() : "");
            if (status) break;
        } else if (a->op == OP_DOWNLOAD_FD) {
            status = fb->Download(a->fd, a->size);
            status = a->func(*a, status, status ? fb_get_error().c_str() : "");
            if (status) break;
        } else if (a->op == OP_COMMAND) {
            status = fb->RawCommand(a->cmd);
            status = a->func(*a, status, status ? fb_get_error().c_str() : "");
            if (status) break;
        } else if (a->op == OP_QUERY) {
            std::string resp;
            status = fb->RawCommand(a->cmd, &resp);
            status = a->func(*a, status, status ? fb_get_error().c_str() : resp.c_str());
            if (status) break;
        } else if (a->op == OP_NOTICE) {
            // We already showed the notice because it's in `Action::msg`.
            fprintf(stderr, "\n");
        } else if (a->op == OP_DOWNLOAD_SPARSE) {
            status = fb->Download(reinterpret_cast<sparse_file*>(a->data));
            status = a->func(*a, status, status ? fb_get_error().c_str() : "");
            if (status) break;
        } else if (a->op == OP_WAIT_FOR_DISCONNECT) {
            fb->WaitForDisconnect();
        } else if (a->op == OP_UPLOAD) {
            status = fb->Upload(reinterpret_cast<const char*>(a->data));
            status = a->func(*a, status, status ? fb_get_error().c_str() : "");
        } else {
            die("unknown action: %d", a->op);
        }
    }
    action_list.clear();
    return status;
}

bool fb_reboot_to_userspace() {
    // First ensure that the queue is flushed.
    fb_execute_queue();

    fprintf(stderr, kStatusFormat, "Rebooting to userspace fastboot");
    verbose("\n");

    if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) {
        fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
        return false;
    }
    fprintf(stderr, "OKAY\n");

    fb_reinit(nullptr);
    return true;
}
