/*
 * Copyright (C) 2008 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 "bootloader.h"
#include "common.h"
extern "C" {
#include "mtdutils/mtdutils.h"
}

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "partitions.hpp"

static int get_bootloader_message_mtd(struct bootloader_message *out, const TWPartition* Partition);
static int set_bootloader_message_mtd(const struct bootloader_message *in, const TWPartition* Partition);
static int get_bootloader_message_block(struct bootloader_message *out, const TWPartition* Partition);
static int set_bootloader_message_block(const struct bootloader_message *in, const TWPartition* Partition);

int get_bootloader_message(struct bootloader_message *out) {
    TWPartition* Part = PartitionManager.Find_Partition_By_Path("/misc");
    if (Part == NULL) {
      //LOGE("Cannot load volume /misc!\n");
      return -1;
    }
    if (Part->Current_File_System == "mtd") {
        return get_bootloader_message_mtd(out, Part);
    } else if (Part->Current_File_System == "emmc") {
        return get_bootloader_message_block(out, Part);
    }
    LOGE("unknown misc partition fs_type \"%s\"\n", Part->Current_File_System.c_str());
    return -1;
}

int set_bootloader_message(const struct bootloader_message *in) {
    TWPartition* Part = PartitionManager.Find_Partition_By_Path("/misc");
    if (Part == NULL) {
      //LOGE("Cannot load volume /misc!\n");
      return -1;
    }
    if (Part->Current_File_System == "mtd") {
        return set_bootloader_message_mtd(in, Part);
    } else if (Part->Current_File_System == "emmc") {
        return set_bootloader_message_block(in, Part);
    }
    LOGE("unknown misc partition fs_type \"%s\"\n", Part->Current_File_System.c_str());
    return -1;
}

// ------------------------------
// for misc partitions on MTD
// ------------------------------

static const int MISC_PAGES = 3;         // number of pages to save
static const int MISC_COMMAND_PAGE = 1;  // bootloader command is this page

static int get_bootloader_message_mtd(struct bootloader_message *out,
                                      const TWPartition* Partition) {
    size_t write_size;
    mtd_scan_partitions();
    const MtdPartition *part = mtd_find_partition_by_name(Partition->Actual_Block_Device.c_str());
    if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
        LOGE("Can't find %s\n", Partition->Actual_Block_Device.c_str());
        return -1;
    }

    MtdReadContext *read = mtd_read_partition(part);
    if (read == NULL) {
        LOGE("Can't open %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }

    const ssize_t size = write_size * MISC_PAGES;
    char data[size];
    ssize_t r = mtd_read_data(read, data, size);
    if (r != size) LOGE("Can't read %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
    mtd_read_close(read);
    if (r != size) return -1;

    memcpy(out, &data[write_size * MISC_COMMAND_PAGE], sizeof(*out));
    return 0;
}
static int set_bootloader_message_mtd(const struct bootloader_message *in,
                                      const TWPartition* Partition) {
    size_t write_size;
    mtd_scan_partitions();
    const MtdPartition *part = mtd_find_partition_by_name(Partition->Actual_Block_Device.c_str());
    if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
        LOGE("Can't find %s\n", Partition->Actual_Block_Device.c_str());
        return -1;
    }

    MtdReadContext *read = mtd_read_partition(part);
    if (read == NULL) {
        LOGE("Can't open %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }

    ssize_t size = write_size * MISC_PAGES;
    char data[size];
    ssize_t r = mtd_read_data(read, data, size);
    if (r != size) LOGE("Can't read %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
    mtd_read_close(read);
    if (r != size) return -1;

    memcpy(&data[write_size * MISC_COMMAND_PAGE], in, sizeof(*in));

    MtdWriteContext *write = mtd_write_partition(part);
    if (write == NULL) {
        LOGE("Can't open %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    if (mtd_write_data(write, data, size) != size) {
        LOGE("Can't write %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        mtd_write_close(write);
        return -1;
    }
    if (mtd_write_close(write)) {
        LOGE("Can't finish %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }

    LOGI("Set boot command \"%s\"\n", in->command[0] != 255 ? in->command : "");
    return 0;
}


// ------------------------------------
// for misc partitions on block devices
// ------------------------------------

static void wait_for_device(const char* fn) {
    int tries = 0;
    int ret;
    struct stat buf;
    do {
        ++tries;
        ret = stat(fn, &buf);
        if (ret) {
            printf("stat %s try %d: %s\n", fn, tries, strerror(errno));
            sleep(1);
        }
    } while (ret && tries < 10);
    if (ret) {
        printf("failed to stat %s\n", fn);
    }
}

static int get_bootloader_message_block(struct bootloader_message *out,
                                        const TWPartition* Partition) {
    wait_for_device(Partition->Actual_Block_Device.c_str());
    FILE* f = fopen(Partition->Actual_Block_Device.c_str(), "rb");
    if (f == NULL) {
        LOGE("Can't open %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    struct bootloader_message temp;
    int count = fread(&temp, sizeof(temp), 1, f);
    if (count != 1) {
        LOGE("Failed reading %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    if (fclose(f) != 0) {
        LOGE("Failed closing %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    memcpy(out, &temp, sizeof(temp));
    return 0;
}

static int set_bootloader_message_block(const struct bootloader_message *in,
                                        const TWPartition* Partition) {
    wait_for_device(Partition->Actual_Block_Device.c_str());
    FILE* f = fopen(Partition->Actual_Block_Device.c_str(), "wb");
    if (f == NULL) {
        LOGE("Can't open %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    int count = fwrite(in, sizeof(*in), 1, f);
    if (count != 1) {
        LOGE("Failed writing %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    if (fclose(f) != 0) {
        LOGE("Failed closing %s\n(%s)\n", Partition->Actual_Block_Device.c_str(), strerror(errno));
        return -1;
    }
    return 0;
}
