/*
 * 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.
 */

#define round_down(a, b) \
    ({ typeof(a) _a = (a); typeof(b) _b = (b); _a - (_a % _b); })

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

#include <algorithm>

#include <sparse/sparse.h>

#include "fastboot.h"

static char ERROR[128];

char *fb_get_error(void)
{
    return ERROR;
}

static int check_response(usb_handle* usb, uint32_t size, char* response) {
    char status[65];

    while (true) {
        int r = usb_read(usb, status, 64);
        if (r < 0) {
            sprintf(ERROR, "status read failed (%s)", strerror(errno));
            usb_close(usb);
            return -1;
        }
        status[r] = 0;

        if (r < 4) {
            sprintf(ERROR, "status malformed (%d bytes)", r);
            usb_close(usb);
            return -1;
        }

        if (!memcmp(status, "INFO", 4)) {
            fprintf(stderr,"(bootloader) %s\n", status + 4);
            continue;
        }

        if (!memcmp(status, "OKAY", 4)) {
            if (response) {
                strcpy(response, (char*) status + 4);
            }
            return 0;
        }

        if (!memcmp(status, "FAIL", 4)) {
            if (r > 4) {
                sprintf(ERROR, "remote: %s", status + 4);
            } else {
                strcpy(ERROR, "remote failure");
            }
            return -1;
        }

        if (!memcmp(status, "DATA", 4) && size > 0){
            uint32_t dsize = strtol(status + 4, 0, 16);
            if (dsize > size) {
                strcpy(ERROR, "data size too large");
                usb_close(usb);
                return -1;
            }
            return dsize;
        }

        strcpy(ERROR,"unknown status code");
        usb_close(usb);
        break;
    }

    return -1;
}

static int _command_start(usb_handle* usb, const char* cmd, uint32_t size, char* response) {
    size_t cmdsize = strlen(cmd);
    if (cmdsize > 64) {
        sprintf(ERROR, "command too large");
        return -1;
    }

    if (response) {
        response[0] = 0;
    }

    if (usb_write(usb, cmd, cmdsize) != static_cast<int>(cmdsize)) {
        sprintf(ERROR, "command write failed (%s)", strerror(errno));
        usb_close(usb);
        return -1;
    }

    return check_response(usb, size, response);
}

static int _command_data(usb_handle* usb, const void* data, uint32_t size) {
    int r = usb_write(usb, data, size);
    if (r < 0) {
        sprintf(ERROR, "data transfer failure (%s)", strerror(errno));
        usb_close(usb);
        return -1;
    }
    if (r != ((int) size)) {
        sprintf(ERROR, "data transfer failure (short transfer)");
        usb_close(usb);
        return -1;
    }
    return r;
}

static int _command_end(usb_handle* usb) {
    return check_response(usb, 0, 0) < 0 ? -1 : 0;
}

static int _command_send(usb_handle* usb, const char* cmd, const void* data, uint32_t size,
                         char* response) {
    if (size == 0) {
        return -1;
    }

    int r = _command_start(usb, cmd, size, response);
    if (r < 0) {
        return -1;
    }

    r = _command_data(usb, data, size);
    if (r < 0) {
        return -1;
    }

    r = _command_end(usb);
    if (r < 0) {
        return -1;
    }

    return size;
}

static int _command_send_no_data(usb_handle* usb, const char* cmd, char* response) {
    return _command_start(usb, cmd, 0, response);
}

int fb_command(usb_handle* usb, const char* cmd) {
    return _command_send_no_data(usb, cmd, 0);
}

int fb_command_response(usb_handle* usb, const char* cmd, char* response) {
    return _command_send_no_data(usb, cmd, response);
}

int fb_download_data(usb_handle* usb, const void* data, uint32_t size) {
    char cmd[64];
    sprintf(cmd, "download:%08x", size);
    return _command_send(usb, cmd, data, size, 0) < 0 ? -1 : 0;
}

#define USB_BUF_SIZE 1024
static char usb_buf[USB_BUF_SIZE];
static int usb_buf_len;

static int fb_download_data_sparse_write(void *priv, const void *data, int len)
{
    int r;
    usb_handle* usb = reinterpret_cast<usb_handle*>(priv);
    int to_write;
    const char* ptr = reinterpret_cast<const char*>(data);

    if (usb_buf_len) {
        to_write = std::min(USB_BUF_SIZE - usb_buf_len, len);

        memcpy(usb_buf + usb_buf_len, ptr, to_write);
        usb_buf_len += to_write;
        ptr += to_write;
        len -= to_write;
    }

    if (usb_buf_len == USB_BUF_SIZE) {
        r = _command_data(usb, usb_buf, USB_BUF_SIZE);
        if (r != USB_BUF_SIZE) {
            return -1;
        }
        usb_buf_len = 0;
    }

    if (len > USB_BUF_SIZE) {
        if (usb_buf_len > 0) {
            sprintf(ERROR, "internal error: usb_buf not empty\n");
            return -1;
        }
        to_write = round_down(len, USB_BUF_SIZE);
        r = _command_data(usb, ptr, to_write);
        if (r != to_write) {
            return -1;
        }
        ptr += to_write;
        len -= to_write;
    }

    if (len > 0) {
        if (len > USB_BUF_SIZE) {
            sprintf(ERROR, "internal error: too much left for usb_buf\n");
            return -1;
        }
        memcpy(usb_buf, ptr, len);
        usb_buf_len = len;
    }

    return 0;
}

static int fb_download_data_sparse_flush(usb_handle* usb) {
    if (usb_buf_len > 0) {
        if (_command_data(usb, usb_buf, usb_buf_len) != usb_buf_len) {
            return -1;
        }
        usb_buf_len = 0;
    }
    return 0;
}

int fb_download_data_sparse(usb_handle* usb, struct sparse_file* s) {
    int size = sparse_file_len(s, true, false);
    if (size <= 0) {
        return -1;
    }

    char cmd[64];
    sprintf(cmd, "download:%08x", size);
    int r = _command_start(usb, cmd, size, 0);
    if (r < 0) {
        return -1;
    }

    r = sparse_file_callback(s, true, false, fb_download_data_sparse_write, usb);
    if (r < 0) {
        return -1;
    }

    r = fb_download_data_sparse_flush(usb);
    if (r < 0) {
        return -1;
    }

    return _command_end(usb);
}
