// 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 "testutil/test_util.h"

#ifndef __APPLE__
#else
#include <mach-o/dyld.h>
#endif

#include <ctype.h>
#include <glog/logging.h>
#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

#include <algorithm>
#include <string>

#include "common/config.h"
// IWYU pragma: no_include <bits/chrono.h>
#include <chrono> // IWYU pragma: keep
#include <filesystem>
#include <fstream>
#include <iostream>
#include <random>

#include "absl/strings/substitute.h"
#include "gflags/gflags.h"
#include "storage/olap_common.h"

DEFINE_bool(gen_out, false, "generate expected check data for test");
DEFINE_bool(
        gen_regression_case, false,
        "generate regression test cases corrresponding to ut cases for ut cases that support it");

const std::string kApacheLicenseHeader =
        R"(// 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.
)";

namespace doris {

static const char* const kSlowTestsEnvVar = "DORIS_ALLOW_SLOW_TESTS";

bool AllowSlowTests() {
    return GetBooleanEnvironmentVariable(kSlowTestsEnvVar);
}

bool GetBooleanEnvironmentVariable(const char* env_var_name) {
    const char* const e = getenv(env_var_name);
    if ((e == nullptr) || (strlen(e) == 0) || (strcasecmp(e, "false") == 0) ||
        (strcasecmp(e, "0") == 0) || (strcasecmp(e, "no") == 0)) {
        return false;
    }
    if ((strcasecmp(e, "true") == 0) || (strcasecmp(e, "1") == 0) || (strcasecmp(e, "yes") == 0)) {
        return true;
    }
    LOG(FATAL) << absl::Substitute("$0: invalid value for environment variable $1", e,
                                   env_var_name);
    return false; // unreachable
}

std::string GetCurrentRunningDir() {
    char exe[PATH_MAX];
    ssize_t r;

#ifdef __APPLE__
    uint32_t size = PATH_MAX;
    if (_NSGetExecutablePath(exe, &size) < 0) {
        return std::string();
    }
    r = strlen(exe) + 1;
#else
    if ((r = readlink("/proc/self/exe", exe, PATH_MAX)) < 0) {
        return std::string();
    }
#endif

    if (r == PATH_MAX) {
        r -= 1;
    }
    exe[r] = 0;
    char* dir = dirname(exe);
    return std::string(dir);
}

void InitConfig() {
    std::string conf_file = std::string(getenv("DORIS_HOME")) + "/conf/be.conf";
    if (!config::init(conf_file.c_str(), false)) {
        fprintf(stderr, "Init config file failed, path %s\n", conf_file.c_str());
        exit(-1);
    }
}

bool equal_ignore_case(std::string lhs, std::string rhs) {
    std::transform(lhs.begin(), lhs.end(), lhs.begin(), ::tolower);
    std::transform(rhs.begin(), rhs.end(), rhs.begin(), ::tolower);
    return lhs == rhs;
}

std::mt19937_64 rng_64(std::chrono::steady_clock::now().time_since_epoch().count());

int rand_rng_int(int l, int r) {
    std::uniform_int_distribution<int> u(l, r);
    return u(rng_64);
}
char rand_rng_char() {
    return (rand_rng_int(0, 1) ? 'a' : 'A') + rand_rng_int(0, 25);
}
std::string rand_rng_string(size_t length) {
    std::string s;
    while (length--) {
        s += rand_rng_char();
    }
    return s;
}
std::string rand_rng_by_type(FieldType fieldType) {
    if (fieldType == FieldType::OLAP_FIELD_TYPE_CHAR) {
        return rand_rng_string(rand_rng_int(1, 8));
    } else if (fieldType == FieldType::OLAP_FIELD_TYPE_VARCHAR) {
        return rand_rng_string(rand_rng_int(1, 128));
    } else if (fieldType == FieldType::OLAP_FIELD_TYPE_STRING) {
        return rand_rng_string(rand_rng_int(1, 100000));
    } else {
        return std::to_string(rand_rng_int(1, 1000000));
    }
}

void load_columns_data_from_file(MutableColumns& columns, DataTypeSerDeSPtrs serders,
                                 char col_spliter, std::set<int> idxes,
                                 const std::string& column_data_file, const cctz::time_zone* tz) {
    ASSERT_EQ(serders.size(), columns.size());
    // Load column data and expected data from CSV files
    std::vector<std::vector<std::string>> res;
    struct stat buff;
    if (stat(column_data_file.c_str(), &buff) == 0) {
        if (S_ISREG(buff.st_mode)) {
            // file
            load_data_from_csv(serders, columns, column_data_file, col_spliter, idxes, tz);
        } else if (S_ISDIR(buff.st_mode)) {
            // dir
            std::filesystem::path fs_path(column_data_file);
            for (const auto& entry : std::filesystem::directory_iterator(fs_path)) {
                std::string file_path = entry.path().string();
                std::cout << "load data from file: " << file_path << std::endl;
                load_data_from_csv(serders, columns, file_path, col_spliter, idxes, tz);
            }
        }
    }
}

// Helper function to load data from CSV, with index which splited by spliter and load to columns
void load_data_from_csv(const DataTypeSerDeSPtrs serders, MutableColumns& columns,
                        const std::string& file_path, const char spliter, const std::set<int> idxes,
                        const cctz::time_zone* tz) {
    ASSERT_EQ(serders.size(), columns.size())
            << "serder size: " << serders.size() << " column size: " << columns.size();
    ASSERT_EQ(serders.size(), idxes.size())
            << "serder size: " << serders.size() << " idxes size: " << idxes.size();
    ASSERT_EQ(serders.size(), *idxes.end())
            << "serder size: " << serders.size() << " idxes size: " << *idxes.end();
    std::ifstream file(file_path);
    if (!file) {
        throw doris::Exception(ErrorCode::INVALID_ARGUMENT, "can not open the file: {} ",
                               file_path);
    }

    std::string line;
    DataTypeSerDe::FormatOptions options;
    options.timezone = tz;
    while (std::getline(file, line)) {
        std::stringstream lineStream(line);
        std::string value;
        int l_idx = 0;
        int c_idx = 0;
        while (std::getline(lineStream, value, spliter)) {
            if (!value.starts_with("//") && idxes.contains(l_idx)) {
                Slice string_slice(value.data(), value.size());
                if (auto st = serders[c_idx]->deserialize_one_cell_from_json(*columns[c_idx],
                                                                             string_slice, options);
                    !st.ok()) {
                    LOG(INFO) << "error in deserialize but continue: " << st.to_string();
                }
                ++c_idx;
            }
            ++l_idx;
        }
    }
    std::cout << "loading data done, file: " << file_path << ", row count: " << columns[0]->size()
              << std::endl;
}
// res_columns[i] is the i-th column of the data
void check_or_generate_res_file(const std::string& res_file_path,
                                const std::vector<std::vector<std::string>>& res_columns) {
    if (res_columns.empty()) {
        return;
    }
    auto row_count = res_columns[0].size();
    if (FLAGS_gen_out) {
        std::ofstream res_file(res_file_path);
        LOG(INFO) << "gen check data with file: " << res_file_path;
        if (!res_file.is_open()) {
            throw std::ios_base::failure("Failed to open file: " + res_file_path);
        }

        for (size_t i = 1; i < res_columns.size(); ++i) {
            EXPECT_EQ(res_columns[i].size(), row_count);
        }
        auto column_count = res_columns.size();
        for (size_t i = 0; i < row_count; ++i) {
            // output one row
            for (size_t j = 0; j < column_count; ++j) {
                const auto& column = res_columns[j];
                // output one column
                res_file << column[i];
                if (j < column_count - 1) {
                    res_file << ";"; // Add semicolon between columns
                }
            }
            if (i < row_count - 1) {
                res_file << "\n";
            }
        }
        res_file.close();
    } else {
        // we read generate file to check result
        LOG(INFO) << "check data with file: " << res_file_path;
        std::ifstream file(res_file_path);
        if (!file) {
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT, "can not open the file: {} ",
                                   res_file_path);
        }

        size_t file_line_count = 0;
        std::string line;
        while (getline(file, line)) {
            file_line_count++;
        }
        EXPECT_EQ(file_line_count, row_count);

        file.clear();
        file.seekg(0, std::ios::beg);

        size_t line_idx = 0;
        while (std::getline(file, line)) {
            std::stringstream line_stream(line);
            std::string value;
            size_t col_idx = 0;
            while (std::getline(line_stream, value, ';')) {
                EXPECT_EQ(value, res_columns[col_idx][line_idx])
                        << "line: " << line_idx << " col: " << col_idx;
                col_idx++;
            }
            line_idx++;
        }
    }
}

} // namespace doris
