/*
 * 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 = "";

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;
            return 0;
        }
    }
    return fread(ptr, size, nitems, stream);
}

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;
            return -1;
        }
    }
    return read(fd, buf, nbyte);
}

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;
            return 0;
        }
    }
    return fwrite(ptr, size, count, stream);
}

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;
            return -1;
        }
    }
    return write(fd, buf, nbyte);
}

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;
            return -1;
        }
    }
    return fsync(fd);
}

