// Copyright 2018 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.

#pragma once

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

#include <fbl/auto_call.h>
#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <runtests-utils/runtests-utils.h>
#include <unittest/unittest.h>

#include "runtests-utils-test-globals.h"


namespace runtests {

static constexpr char kExpectedJSONOutputPrefix[] = "{\n  \"tests\": [\n";
// We don't want to count the null terminator.
static constexpr size_t kExpectedJSONOutputPrefixSize =
    sizeof(kExpectedJSONOutputPrefix) - 1;

// Creates a script file with given contents in its constructor and deletes it
// in its destructor.
class ScopedScriptFile {

public:
    // |path| is the path of the file to be created. Should start with
    // kMemFsPath. |contents| are the script contents. Shebang line will be
    // added automatically.
    ScopedScriptFile(const fbl::StringPiece path,
                     const fbl::StringPiece contents);
    ~ScopedScriptFile();
    fbl::StringPiece path() const;

private:
    const fbl::StringPiece path_;
};


// Creates a script file with given contents in its constructor and deletes it
// in its destructor.
class ScopedTestFile {

public:
    // |path| is the path of the file to be created. Should start with kMemFsPath.
    // |contents| are the script contents. Shebang line will be added automatically.
    ScopedTestFile(const fbl::StringPiece path, const fbl::StringPiece file);
    ~ScopedTestFile();
    fbl::StringPiece path() const;

private:
    const fbl::StringPiece path_;
};


// Creates a subdirectory of TestFsRoot() in its constructor and deletes it in
// its destructor.
class ScopedTestDir {

public:
    ScopedTestDir()
        : basename_(NextBasename()), path_(JoinPath(TestFsRoot(), basename_)) {
        if (mkdir(path_.c_str(), 0755)) {
            printf("FAILURE: mkdir failed to open %s: %s\n", path_.c_str(),
                   strerror(errno));
            exit(1);
        }
    }
    ~ScopedTestDir() { CleanUpDir(path_.c_str()); }
    const char* basename() { return basename_.c_str(); }
    const char* path() { return path_.c_str(); }

private:
    fbl::String NextBasename() {
        // More than big enough to print INT_MAX.
        char buf[64];
        sprintf(buf, "%d", num_test_dirs_created_++);
        return fbl::String(buf);
    }

    // Recursively removes the directory at |dir_path| and its contents.
    static void CleanUpDir(const char* dir_path) {
        struct dirent* entry;
        DIR* dp;

        dp = opendir(dir_path);
        if (dp == nullptr) {
            // File found; remove it.
            remove(dir_path);
            return;
        }

        while ((entry = readdir(dp))) {
            // Skip "." and "..".
            if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
                continue;
            }
            fbl::String sub_dir_name = JoinPath(dir_path, entry->d_name);
            CleanUpDir(sub_dir_name.c_str());
        }
        closedir(dp);

        // Directory is now empty: remove it.
        rmdir(dir_path);
    }

    const fbl::String basename_;
    const fbl::String path_;

    // Used to generate unique subdirectories of TestFsRoot().
    static int num_test_dirs_created_;
};


class TestStopwatch : public Stopwatch {
public:
    void Start() override { start_called_ = true; }
    int64_t DurationInMsecs() override {
        BEGIN_HELPER;
        EXPECT_TRUE(start_called_);
        END_HELPER;
        return 14u;
    }

private:
    bool start_called_ = false;
};


// Returns the number of files or subdirectories in a given directory.
int NumEntriesInDir(const char* dir_path);

// Computes the relative path within |output_dir| of the output file of the
// test at |test_path|, setting |output_file_rel_path| as its value if
// successful.
// Returns true iff successful.
bool GetOutputFileRelPath(const fbl::StringPiece& output_dir,
                          const fbl::StringPiece& test_path,
                          fbl::String* output_file_rel_path);

} // namespace runtests
