// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <fbl/algorithm.h>
#include <fbl/unique_fd.h>
#include <zircon/syscalls.h>

#include "filesystems.h"
#include "misc.h"

#define MB (1 << 20)
#define PRINT_SIZE (MB * 100)

namespace {

enum MountType {
    DoRemount,
    DontRemount,
};

// Test writing as much as we can to a file until we run
// out of space
template <MountType mt>
bool test_maxfile(void) {
    BEGIN_TEST;

    if (!test_info->can_be_mounted && mt == DoRemount) {
        fprintf(stderr, "Filesystem cannot be mounted; cannot remount\n");
        return true;
    }

    // TODO(ZX-1735): We avoid making files that consume more than half
    // of physical memory. When we can page out files, this restriction
    // should be removed.
    const size_t physmem = zx_system_get_physmem();
    const size_t max_cap = physmem / 2;

    fbl::unique_fd fd(open("::bigfile", O_CREAT | O_RDWR, 0644));
    ASSERT_TRUE(fd);
    char data_a[8192];
    char data_b[8192];
    char data_c[8192];
    memset(data_a, 0xaa, sizeof(data_a));
    memset(data_b, 0xbb, sizeof(data_b));
    memset(data_c, 0xcc, sizeof(data_c));
    size_t sz = 0;
    ssize_t r;

    auto rotate = [&](const char* data) {
        if (data == data_a) {
            return data_b;
        } else if (data == data_b) {
            return data_c;
        } else {
            return data_a;
        }
    };

    const char* data = data_a;
    for (;;) {
        if (sz >= max_cap) {
            fprintf(stderr, "Approaching physical memory capacity: %zd bytes\n", sz);
            r = 0;
            break;
        }

        if ((r = write(fd.get(), data, sizeof(data_a))) < 0) {
            fprintf(stderr, "bigfile received error: %s\n", strerror(errno));
            if ((errno == EFBIG) || (errno == ENOSPC)) {
                // Either the file should be too big (EFBIG) or the file should
                // consume the whole volume (ENOSPC).
                fprintf(stderr, "(This was an expected error)\n");
                r = 0;
            }
            break;
        }
        if ((sz + r) % PRINT_SIZE < (sz % PRINT_SIZE)) {
            fprintf(stderr, "wrote %lu MB\n", (sz + r) / MB);
        }
        sz += r;
        ASSERT_EQ(r, sizeof(data_a));

        // Rotate which data buffer we use
        data = rotate(data);
    }
    ASSERT_EQ(r, 0, "Saw an unexpected error from write");
    fprintf(stderr, "wrote %lu bytes\n", sz);

    struct stat buf;
    ASSERT_EQ(fstat(fd.get(), &buf), 0, "Couldn't stat max file");
    ASSERT_EQ(buf.st_size, static_cast<ssize_t>(sz), "Unexpected max file size");

    // Try closing, re-opening, and verifying the file
    ASSERT_EQ(close(fd.release()), 0);
    if (mt == DoRemount) {
        ASSERT_TRUE(check_remount(), "Could not remount filesystem");
    }
    fd.reset(open("::bigfile", O_RDWR, 0644));
    ASSERT_TRUE(fd);
    ASSERT_EQ(fstat(fd.get(), &buf), 0, "Couldn't stat max file");
    ASSERT_EQ(buf.st_size, static_cast<ssize_t>(sz), "Unexpected max file size");
    char readbuf[8192];
    size_t bytes_read = 0;
    data = data_a;
    while (bytes_read < sz) {
        r = read(fd.get(), readbuf, sizeof(readbuf));
        ASSERT_EQ(r, static_cast<ssize_t>(fbl::min(sz - bytes_read, sizeof(readbuf))));
        ASSERT_EQ(memcmp(readbuf, data, r), 0, "File failed to verify");
        data = rotate(data);
        bytes_read += r;
    }

    ASSERT_EQ(bytes_read, sz);

    ASSERT_EQ(unlink("::bigfile"), 0);
    ASSERT_EQ(close(fd.release()), 0);
    END_TEST;
}

// Test writing to two files, in alternation, until we run out
// of space. For trivial (sequential) block allocation policies,
// this will create two large files with non-contiguous block
// allocations.
template <MountType mt>
bool TestZippedMaxfiles(void) {
    BEGIN_TEST;

    if (!test_info->can_be_mounted && mt == DoRemount) {
        fprintf(stderr, "Filesystem cannot be mounted; cannot remount\n");
        return true;
    }

    // TODO(ZX-1735): We avoid making files that consume more than half
    // of physical memory. When we can page out files, this restriction
    // should be removed.
    const size_t physmem = zx_system_get_physmem();
    const size_t max_cap = physmem / 4;

    fbl::unique_fd fda(open("::bigfile-A", O_CREAT | O_RDWR, 0644));
    fbl::unique_fd fdb(open("::bigfile-B", O_CREAT | O_RDWR, 0644));
    ASSERT_TRUE(fda);
    ASSERT_TRUE(fdb);
    char data_a[8192];
    char data_b[8192];
    memset(data_a, 0xaa, sizeof(data_a));
    memset(data_b, 0xbb, sizeof(data_b));
    size_t sz_a = 0;
    size_t sz_b = 0;
    ssize_t r;

    size_t* sz = &sz_a;
    int fd = fda.get();
    const char* data = data_a;
    for (;;) {
        if (*sz >= max_cap) {
            fprintf(stderr, "Approaching physical memory capacity: %zd bytes\n", *sz);
            r = 0;
            break;
        }

        if ((r = write(fd, data, sizeof(data_a))) <= 0) {
            fprintf(stderr, "bigfile received error: %s\n", strerror(errno));
            // Either the file should be too big (EFBIG) or the file should
            // consume the whole volume (ENOSPC).
            ASSERT_TRUE(errno == EFBIG || errno == ENOSPC);
            fprintf(stderr, "(This was an expected error)\n");
            break;
        }
        if ((*sz + r) % PRINT_SIZE < (*sz % PRINT_SIZE)) {
            fprintf(stderr, "wrote %lu MB\n", (*sz + r) / MB);
        }
        *sz += r;
        ASSERT_EQ(r, sizeof(data_a));

        fd = (fd == fda.get()) ? fdb.get() : fda.get();
        data = (data == data_a) ? data_b : data_a;
        sz = (sz == &sz_a) ? &sz_b : &sz_a;
    }
    fprintf(stderr, "wrote %lu bytes (to A)\n", sz_a);
    fprintf(stderr, "wrote %lu bytes (to B)\n", sz_b);

    struct stat buf;
    ASSERT_EQ(fstat(fda.get(), &buf), 0, "Couldn't stat max file");
    ASSERT_EQ(buf.st_size, static_cast<ssize_t>(sz_a), "Unexpected max file size");
    ASSERT_EQ(fstat(fdb.get(), &buf), 0, "Couldn't stat max file");
    ASSERT_EQ(buf.st_size, static_cast<ssize_t>(sz_b), "Unexpected max file size");

    // Try closing, re-opening, and verifying the file
    ASSERT_EQ(close(fda.release()), 0);
    ASSERT_EQ(close(fdb.release()), 0);
    if (mt == DoRemount) {
        ASSERT_TRUE(check_remount(), "Could not remount filesystem");
    }
    fda.reset(open("::bigfile-A", O_RDWR, 0644));
    fdb.reset(open("::bigfile-B", O_RDWR, 0644));
    ASSERT_TRUE(fda);
    ASSERT_TRUE(fdb);

    char readbuf[8192];
    size_t bytes_read_a = 0;
    size_t bytes_read_b = 0;

    fd = fda.get();
    data = data_a;
    sz = &sz_a;
    size_t* bytes_read = &bytes_read_a;
    while (*bytes_read < *sz) {
        r = read(fd, readbuf, sizeof(readbuf));
        ASSERT_EQ(r, static_cast<ssize_t>(fbl::min(*sz - *bytes_read, sizeof(readbuf))));
        ASSERT_EQ(memcmp(readbuf, data, r), 0, "File failed to verify");
        *bytes_read += r;

        fd = (fd == fda.get()) ? fdb.get() : fda.get();
        data = (data == data_a) ? data_b : data_a;
        sz = (sz == &sz_a) ? &sz_b : &sz_a;
        bytes_read = (bytes_read == &bytes_read_a) ? &bytes_read_b : &bytes_read_a;
    }

    ASSERT_EQ(bytes_read_a, sz_a);
    ASSERT_EQ(bytes_read_b, sz_b);

    ASSERT_EQ(unlink("::bigfile-A"), 0);
    ASSERT_EQ(unlink("::bigfile-B"), 0);
    ASSERT_EQ(close(fda.release()), 0);
    ASSERT_EQ(close(fdb.release()), 0);

    END_TEST;
}

// Disk must be at least this large to exceed the maximum transaction limit during delayed data
// allocation on non-FVM-backed Minfs partitions.
const test_disk_t disk = {
    .block_count = 1LLU << 20,
    .block_size = 1LLU << 9,
    .slice_size = 1LLU << 23,
};

}  // namespace

RUN_FOR_ALL_FILESYSTEMS_SIZE(maxfile_tests, disk,
    RUN_TEST_LARGE((test_maxfile<DontRemount>))
    RUN_TEST_LARGE((test_maxfile<DoRemount>))
    RUN_TEST_LARGE((TestZippedMaxfiles<DontRemount>))
    RUN_TEST_LARGE((TestZippedMaxfiles<DoRemount>))
)
