// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "runtime/tmp_file_mgr.h"

#include <gtest/gtest.h>

#include <boost/filesystem.hpp>
#include <boost/scoped_ptr.hpp>
#include <cstdlib>

#include "gen_cpp/Types_types.h" // for TUniqueId
#include "util/disk_info.h"
#include "util/filesystem_util.h"
#include "util/logging.h"
#include "util/metrics.h"

using boost::filesystem::path;
using std::string;
using std::vector;
using std::set;

namespace doris {

class TmpFileMgrTest : public ::testing::Test {
protected:
    // Check that metric values are consistent with TmpFileMgr state.
    void check_metrics(TmpFileMgr* tmp_file_mgr) {
        std::vector<TmpFileMgr::DeviceId> active = tmp_file_mgr->active_tmp_devices();
        int64_t active_metric = DorisMetrics::instance()
                                        ->metric_registry()
                                        ->get_entity("server")
                                        ->get_metric("active_scratch_dirs")
                                        .value();
        EXPECT_EQ(active.size(), active_metric);
    }
};

// Regression test for IMPALA-2160. Verify that temporary file manager allocates blocks
// at the expected file offsets and expands the temporary file to the correct size.
TEST_F(TmpFileMgrTest, TestFileAllocation) {
    TmpFileMgr tmp_file_mgr;
    EXPECT_TRUE(tmp_file_mgr.init().ok());
    // Default configuration should give us one temporary device.
    EXPECT_EQ(1, tmp_file_mgr.num_active_tmp_devices());
    std::vector<TmpFileMgr::DeviceId> tmp_devices = tmp_file_mgr.active_tmp_devices();
    EXPECT_EQ(1, tmp_devices.size());
    TUniqueId id;
    TmpFileMgr::File* file;
    Status status = tmp_file_mgr.get_file(tmp_devices[0], id, &file);
    EXPECT_TRUE(status.ok());
    EXPECT_TRUE(file != NULL);
    // Apply writes of variable sizes and check space was allocated correctly.
    int64_t write_sizes[] = {1, 10, 1024, 4, 1024 * 1024 * 8, 1024 * 1024 * 8, 16, 10};
    int num_write_sizes = sizeof(write_sizes) / sizeof(write_sizes[0]);
    int64_t next_offset = 0;
    for (int i = 0; i < num_write_sizes; ++i) {
        int64_t offset;
        status = file->allocate_space(write_sizes[i], &offset);
        EXPECT_TRUE(status.ok());
        EXPECT_EQ(next_offset, offset);
        next_offset = offset + write_sizes[i];
        EXPECT_EQ(next_offset, boost::filesystem::file_size(file->path()));
    }
    // Check that cleanup is correct.
    status = file->remove();
    EXPECT_TRUE(status.ok());
    EXPECT_FALSE(boost::filesystem::exists(file->path()));
    // check_metrics(&tmp_file_mgr);
}
// Test that we can do initialization with two directories on same device and
// that validations prevents duplication of directories.
TEST_F(TmpFileMgrTest, TestOneDirPerDevice) {
    std::vector<string> tmp_dirs;
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.1");
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.2");
    for (int i = 0; i < tmp_dirs.size(); ++i) {
        EXPECT_TRUE(FileSystemUtil::create_directory(tmp_dirs[i]).ok());
    }
    TmpFileMgr tmp_file_mgr;
    tmp_file_mgr.init_custom(tmp_dirs, true);

    // Only the first directory should be used.
    EXPECT_EQ(1, tmp_file_mgr.num_active_tmp_devices());
    std::vector<TmpFileMgr::DeviceId> devices = tmp_file_mgr.active_tmp_devices();
    EXPECT_EQ(1, devices.size());
    TUniqueId id;
    TmpFileMgr::File* file;
    EXPECT_TRUE(tmp_file_mgr.get_file(devices[0], id, &file).ok());
    // Check the prefix is the expected temporary directory.
    EXPECT_EQ(0, file->path().find(tmp_dirs[0]));
    FileSystemUtil::remove_paths(tmp_dirs);
    // check_metrics(&tmp_file_mgr);
}

// Test that we can do custom initialization with two dirs on same device.
TEST_F(TmpFileMgrTest, TestMultiDirsPerDevice) {
    std::vector<string> tmp_dirs;
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.1");
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.2");
    for (int i = 0; i < tmp_dirs.size(); ++i) {
        EXPECT_TRUE(FileSystemUtil::create_directory(tmp_dirs[i]).ok());
    }
    TmpFileMgr tmp_file_mgr;
    tmp_file_mgr.init_custom(tmp_dirs, false);

    // Both directories should be used.
    EXPECT_EQ(2, tmp_file_mgr.num_active_tmp_devices());
    std::vector<TmpFileMgr::DeviceId> devices = tmp_file_mgr.active_tmp_devices();
    EXPECT_EQ(2, devices.size());
    for (int i = 0; i < tmp_dirs.size(); ++i) {
        EXPECT_EQ(0, tmp_file_mgr.get_tmp_dir_path(devices[i]).find(tmp_dirs[i]));
        TUniqueId id;
        TmpFileMgr::File* file;
        EXPECT_TRUE(tmp_file_mgr.get_file(devices[i], id, &file).ok());
        // Check the prefix is the expected temporary directory.
        EXPECT_EQ(0, file->path().find(tmp_dirs[i]));
    }
    FileSystemUtil::remove_paths(tmp_dirs);
    // check_metrics(&tmp_file_mgr);
}

// Test that reporting a write error is possible but does not result in
// blacklisting, which is disabled.
TEST_F(TmpFileMgrTest, TestReportError) {
    std::vector<string> tmp_dirs;
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.1");
    tmp_dirs.push_back("/tmp/tmp-file-mgr-test.2");
    for (int i = 0; i < tmp_dirs.size(); ++i) {
        EXPECT_TRUE(FileSystemUtil::create_directory(tmp_dirs[i]).ok());
    }
    TmpFileMgr tmp_file_mgr;
    tmp_file_mgr.init_custom(tmp_dirs, false);

    // Both directories should be used.
    std::vector<TmpFileMgr::DeviceId> devices = tmp_file_mgr.active_tmp_devices();
    EXPECT_EQ(2, devices.size());
    // check_metrics(&tmp_file_mgr);

    // Inject an error on one device so that we can validate it is handled correctly.
    TUniqueId id;
    int good_device = 0;
    int bad_device = 1;
    TmpFileMgr::File* bad_file;
    EXPECT_TRUE(tmp_file_mgr.get_file(devices[bad_device], id, &bad_file).ok());
    // ErrorMsg errmsg(TErrorCode::GENERAL, "A fake error");
    // bad_file->ReportIOError(errmsg);
    bad_file->report_io_error("A fake error");

    // Blacklisting is disabled.
    EXPECT_FALSE(bad_file->is_blacklisted());
    // The second device should still be active.
    EXPECT_EQ(2, tmp_file_mgr.num_active_tmp_devices());
    std::vector<TmpFileMgr::DeviceId> devices_after = tmp_file_mgr.active_tmp_devices();
    EXPECT_EQ(2, devices_after.size());
    // check_metrics(&tmp_file_mgr);

    // Attempts to expand bad file should succeed.
    int64_t offset;
    EXPECT_TRUE(bad_file->allocate_space(128, &offset).ok());
    EXPECT_TRUE(bad_file->remove().ok());
    // The good device should still be usable.
    TmpFileMgr::File* good_file;
    EXPECT_TRUE(tmp_file_mgr.get_file(devices[good_device], id, &good_file).ok());
    EXPECT_TRUE(good_file != NULL);
    EXPECT_TRUE(good_file->allocate_space(128, &offset).ok());
    // Attempts to allocate new files on bad device should succeed.
    EXPECT_TRUE(tmp_file_mgr.get_file(devices[bad_device], id, &bad_file).ok());
    FileSystemUtil::remove_paths(tmp_dirs);
    // check_metrics(&tmp_file_mgr);
}

TEST_F(TmpFileMgrTest, TestAllocateFails) {
    string tmp_dir("/tmp/tmp-file-mgr-test.1");
    string scratch_subdir = tmp_dir + "/doris-scratch";
    std::vector<string> tmp_dirs(1, tmp_dir);
    EXPECT_TRUE(FileSystemUtil::create_directory(tmp_dir).ok());
    TmpFileMgr tmp_file_mgr;
    tmp_file_mgr.init_custom(tmp_dirs, false);

    TUniqueId id;
    TmpFileMgr::File* allocated_file1;
    TmpFileMgr::File* allocated_file2;
    int64_t offset;
    EXPECT_TRUE(tmp_file_mgr.get_file(0, id, &allocated_file1).ok());
    EXPECT_TRUE(tmp_file_mgr.get_file(0, id, &allocated_file2).ok());
    EXPECT_TRUE(allocated_file1->allocate_space(1, &offset).ok());

    // Make scratch non-writable and test for allocation errors at different stages:
    // new file creation, files with no allocated blocks. files with allocated space.
    chmod(scratch_subdir.c_str(), 0);
    // allocated_file1 already has space allocated.
    EXPECT_FALSE(allocated_file1->allocate_space(1, &offset).ok());
    // allocated_file2 has no space allocated.
    EXPECT_FALSE(allocated_file2->allocate_space(1, &offset).ok());
    // Creating a new File object can succeed because it is not immediately created on disk.
    TmpFileMgr::File* unallocated_file;
    EXPECT_TRUE(tmp_file_mgr.get_file(0, id, &unallocated_file).ok());

    chmod(scratch_subdir.c_str(), S_IRWXU);
    FileSystemUtil::remove_paths(tmp_dirs);
}

} // end namespace doris

int main(int argc, char** argv) {
    // std::string conffile = std::string(getenv("DORIS_HOME")) + "/conf/be.conf";
    // if (!doris::config::init(conffile.c_str(), false)) {
    //     fprintf(stderr, "error read config file. \n");
    //     return -1;
    // }
    doris::config::query_scratch_dirs = "/tmp";
    doris::init_glog("be-test");
    ::testing::InitGoogleTest(&argc, argv);

    doris::DiskInfo::init();

    return RUN_ALL_TESTS();
}
