/*
 * Copyright 2024-present Alibaba Inc.
 *
 * 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.
 */

//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

// Assert utilities is adapted from RocksDB
// https://github.com/facebook/rocksdb/blob/main/test_util/testharness.cc

// Copyright 2024 Google LLC.
//
// 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.

// UniqueTestDirectory utility is adapted from LiteRT
// https://github.com/google-ai-edge/LiteRT/blob/main/litert/test/common.cc

#include "paimon/testing/utils/testharness.h"

#include <unistd.h>

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>

#include "paimon/common/utils/string_utils.h"
#include "paimon/common/utils/uuid.h"
#include "paimon/fs/file_system.h"
#include "paimon/fs/file_system_factory.h"
#include "paimon/status.h"

namespace paimon::test {

std::string GetDataDir() {
    const auto result = std::getenv("PAIMON_TEST_DATA");
    if (!result || !result[0]) {
        return "test/test_data/";
    }
    return std::string(result);
}

std::map<std::string, std::string> GetJindoTestOptions() {
    const char* home = std::getenv("HOME");
    std::string home_str = "";
    if (home) {
        home_str = std::string(home);
    }
    std::string config_file_path = home_str + "/.osscredentials";
    std::ifstream config_file(config_file_path);
    std::string access_key_id = "";
    std::string access_key_secret = "";
    if (config_file.is_open()) {
        std::string line;
        while (std::getline(config_file, line)) {
            std::vector<std::string> key_value = StringUtils::Split(line, "=");
            if (key_value.size() != 2) {
                continue;
            }
            if (key_value[0].find("accessid") != std::string::npos) {
                StringUtils::Trim(&key_value[1]);
                access_key_id = key_value[1];
            }
            if (key_value[0].find("accesskey") != std::string::npos) {
                StringUtils::Trim(&key_value[1]);
                access_key_secret = key_value[1];
            }
        }
        config_file.close();
    }
    std::map<std::string, std::string> options = {
        {"fs.oss.bucket.paimon-unittest.endpoint", "oss-cn-hangzhou-zmf.aliyuncs.com"},
        {"fs.oss.bucket.paimon-unittest.accessKeyId", access_key_id},
        {"fs.oss.bucket.paimon-unittest.accessKeySecret", access_key_secret},
        {"fs.oss.user", "paimon"},
    };
    return options;
}
std::string GetJindoTestDir() {
    static const std::string dir = "oss://paimon-unittest/temp/";
    return dir;
}

int64_t RandomNumber(int64_t min, int64_t max) {
    static thread_local std::mt19937 generator(
        std::random_device{}());  // NOLINT(whitespace/braces)
    std::uniform_int_distribution<int64_t> distribution(min, max);
    return distribution(generator);
}

std::string GetPidStr() {
    return std::to_string(getpid());
}

::testing::AssertionResult AssertStatus(const char* s_expr, const Status& s) {
    if (s.ok()) {
        return ::testing::AssertionSuccess();
    } else {
        return ::testing::AssertionFailure() << s_expr << std::endl << s.ToString();
    }
}

std::unique_ptr<UniqueTestDirectory> UniqueTestDirectory::Create(const std::string& fs_identifier) {
    static const size_t kMaxTries = 1000;
    std::string tmp_dir = fs_identifier == "jindo"
                              ? GetJindoTestDir()
                              : std::filesystem::temp_directory_path().string() + "/";
    std::map<std::string, std::string> fs_options =
        fs_identifier == "jindo" ? GetJindoTestOptions() : std::map<std::string, std::string>();
    auto fs = FileSystemFactory::Get(fs_identifier, tmp_dir, fs_options);
    if (!fs.ok()) {
        return nullptr;
    }
    for (size_t i = 0; i < kMaxTries; ++i) {
        std::string uuid;
        if (!UUID::Generate(&uuid)) {
            continue;
        }
        std::string test_dir = tmp_dir + "paimon_test_" + uuid;
        auto is_exist = fs.value()->Exists(test_dir);
        if (!is_exist.ok() || is_exist.value()) {
            continue;
        }
        auto status = fs.value()->Mkdirs(test_dir);
        if (status.ok()) {
            return std::unique_ptr<UniqueTestDirectory>(
                new UniqueTestDirectory(test_dir, std::move(fs).value()));
        }
    }
    return nullptr;
}

UniqueTestDirectory::~UniqueTestDirectory() {
    auto is_exist = fs_->Exists(tmpdir_);
    assert(is_exist.ok());
    if (is_exist.value()) {
        [[maybe_unused]] auto status = fs_->Delete(tmpdir_, /*recursive=*/true);
        assert(status.ok());
    }
    fs_.reset();
}

bool TestUtil::CopyDirectory(const std::filesystem::path& source,
                             const std::filesystem::path& destination) {
    namespace fs = std::filesystem;
    try {
        if (!fs::exists(destination)) {
            fs::create_directories(destination);
        }

        for (const auto& entry : fs::directory_iterator(source)) {
            const auto& source_path = entry.path();
            auto destination_path = destination / source_path.filename();

            if (fs::is_directory(source_path)) {
                CopyDirectory(source_path, destination_path);
            } else if (fs::is_regular_file(source_path)) {
                fs::copy(source_path, destination_path, fs::copy_options::overwrite_existing);
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "Error while copying directory: " << e.what() << std::endl;
        return false;
    }
    return true;
}

}  // namespace paimon::test
