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

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#include "config.h"
#include "ota_io.h"

static std::map<intptr_t, const char*> filename_cache;
static std::string read_fault_file_name = "";
static std::string write_fault_file_name = "";
static std::string fsync_fault_file_name = "";
bool have_eio_error = false;

static bool get_hit_file(const char* cached_path, std::string ffn) {
    return should_hit_cache()
        ? !strncmp(cached_path, OTAIO_CACHE_FNAME, strlen(cached_path))
        : !strncmp(cached_path, ffn.c_str(), strlen(cached_path));
}

void ota_set_fault_files() {
    if (should_fault_inject(OTAIO_READ)) {
        read_fault_file_name = fault_fname(OTAIO_READ);
    }
    if (should_fault_inject(OTAIO_WRITE)) {
        write_fault_file_name = fault_fname(OTAIO_WRITE);
    }
    if (should_fault_inject(OTAIO_FSYNC)) {
        fsync_fault_file_name = fault_fname(OTAIO_FSYNC);
    }
}

int ota_open(const char* path, int oflags) {
    // Let the caller handle errors; we do not care if open succeeds or fails
    int fd = open(path, oflags);
    filename_cache[fd] = path;
    return fd;
}

int ota_open(const char* path, int oflags, mode_t mode) {
    int fd = open(path, oflags, mode);
    filename_cache[fd] = path;
    return fd; }

FILE* ota_fopen(const char* path, const char* mode) {
    FILE* fh = fopen(path, mode);
    filename_cache[(intptr_t)fh] = path;
    return fh;
}

int ota_close(int fd) {
    // descriptors can be reused, so make sure not to leave them in the cache
    filename_cache.erase(fd);
    return close(fd);
}

int ota_fclose(FILE* fh) {
    filename_cache.erase((intptr_t)fh);
    return fclose(fh);
}

size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
    if (should_fault_inject(OTAIO_READ)) {
        auto cached = filename_cache.find((intptr_t)stream);
        const char* cached_path = cached->second;
        if (cached != filename_cache.end() &&
                get_hit_file(cached_path, read_fault_file_name)) {
            read_fault_file_name = "";
            errno = EIO;
            have_eio_error = true;
            return 0;
        }
    }
    size_t status = fread(ptr, size, nitems, stream);
    // If I/O error occurs, set the retry-update flag.
    if (status != nitems && errno == EIO) {
        have_eio_error = true;
    }
    return status;
}

ssize_t ota_read(int fd, void* buf, size_t nbyte) {
    if (should_fault_inject(OTAIO_READ)) {
        auto cached = filename_cache.find(fd);
        const char* cached_path = cached->second;
        if (cached != filename_cache.end()
                && get_hit_file(cached_path, read_fault_file_name)) {
            read_fault_file_name = "";
            errno = EIO;
            have_eio_error = true;
            return -1;
        }
    }
    ssize_t status = read(fd, buf, nbyte);
    if (status == -1 && errno == EIO) {
        have_eio_error = true;
    }
    return status;
}

size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) {
    if (should_fault_inject(OTAIO_WRITE)) {
        auto cached = filename_cache.find((intptr_t)stream);
        const char* cached_path = cached->second;
        if (cached != filename_cache.end() &&
                get_hit_file(cached_path, write_fault_file_name)) {
            write_fault_file_name = "";
            errno = EIO;
            have_eio_error = true;
            return 0;
        }
    }
    size_t status = fwrite(ptr, size, count, stream);
    if (status != count && errno == EIO) {
        have_eio_error = true;
    }
    return status;
}

ssize_t ota_write(int fd, const void* buf, size_t nbyte) {
    if (should_fault_inject(OTAIO_WRITE)) {
        auto cached = filename_cache.find(fd);
        const char* cached_path = cached->second;
        if (cached != filename_cache.end() &&
                get_hit_file(cached_path, write_fault_file_name)) {
            write_fault_file_name = "";
            errno = EIO;
            have_eio_error = true;
            return -1;
        }
    }
    ssize_t status = write(fd, buf, nbyte);
    if (status == -1 && errno == EIO) {
        have_eio_error = true;
    }
    return status;
}

int ota_fsync(int fd) {
    if (should_fault_inject(OTAIO_FSYNC)) {
        auto cached = filename_cache.find(fd);
        const char* cached_path = cached->second;
        if (cached != filename_cache.end() &&
                get_hit_file(cached_path, fsync_fault_file_name)) {
            fsync_fault_file_name = "";
            errno = EIO;
            have_eio_error = true;
            return -1;
        }
    }
    int status = fsync(fd);
    if (status == -1 && errno == EIO) {
        have_eio_error = true;
    }
    return status;
}

