/*
 * 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 "paimon/fs/local/local_file.h"

#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

#include <cerrno>
#include <cstring>
#include <utility>

#include "fmt/format.h"
#include "paimon/common/factories/io_hook.h"
#include "paimon/common/utils/math.h"
#include "paimon/common/utils/path_util.h"
#include "paimon/common/utils/string_utils.h"

namespace paimon {

// TODO(yonghao.fyh): move io_hook.h to test/test_util and add a HookLocalFileSystem only for test
#define CHECK_HOOK()                             \
    if (hook_) {                                 \
        PAIMON_RETURN_NOT_OK(hook_->Try(path_)); \
    }

Result<std::unique_ptr<LocalFile>> LocalFile::Create(const std::string& path_string) {
    if (path_string.empty()) {
        PAIMON_ASSIGN_OR_RAISE(std::string current_path, PathUtil::GetWorkingDirectory());
        return std::unique_ptr<LocalFile>(new LocalFile(current_path));
    }

    // local file system does not support path_string with scheme, e.g., "file:/tmp" will be
    // rewritten to "/tmp"
    PAIMON_ASSIGN_OR_RAISE(Path path, PathUtil::ToPath(path_string));
    if (!path.scheme.empty() && StringUtils::ToLowerCase(path.scheme) != "file") {
        return Status::Invalid(fmt::format("invalid scheme {} for local file system", path.scheme));
    }
    if (path.path.empty() || path.path[0] != '/') {
        PAIMON_ASSIGN_OR_RAISE(std::string current_path, PathUtil::GetWorkingDirectory());
        return std::unique_ptr<LocalFile>(
            new LocalFile(PathUtil::JoinPath(current_path, path.path)));
    }
    return std::unique_ptr<LocalFile>(new LocalFile(path.path));
}

LocalFile::LocalFile(const std::string& path) : path_(path), hook_(IOHook::GetInstance()) {}

LocalFile::~LocalFile() {
    if (file_) {
        std::fclose(file_);
    }
}

Result<bool> LocalFile::Exists() const {
    CHECK_HOOK();
    if (access(path_.c_str(), F_OK) == 0) {
        return true;
    } else if (errno == ENOENT) {
        return false;
    }
    int32_t cur_errno = errno;
    return Status::IOError(
        fmt::format("path '{}' check exists fail, ec: {}", path_, std::strerror(cur_errno)));
}

Result<bool> LocalFile::IsFile() const {
    CHECK_HOOK();
    bool is_file = false;
    struct stat buf;
    if (stat(path_.c_str(), &buf) < 0) {
        return Status::IOError(
            fmt::format("path '{}' check isFile fail, ec: {}", path_, std::strerror(errno)));
    }
    if (S_ISREG(buf.st_mode)) {
        is_file = true;
    }
    return is_file;
}

Result<bool> LocalFile::IsDir() const {
    CHECK_HOOK();
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, GetFileStatus());
    return file_status.IsDir();
}

Status LocalFile::List(std::vector<std::string>* file_list) const {
    CHECK_HOOK();
    file_list->clear();
    DIR* dp;
    struct dirent* ep;
    dp = opendir(path_.c_str());
    if (dp == nullptr) {
        int32_t cur_errno = errno;
        return Status::IOError(
            fmt::format("list path '{}' fail, ec: {}", path_, std::strerror(cur_errno)));
    }

    while ((ep = readdir(dp)) != nullptr) {
        if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) {
            continue;
        }
        file_list->push_back(ep->d_name);
    }
    if (closedir(dp) < 0) {
        file_list->clear();
        int32_t cur_errno = errno;
        return Status::IOError(
            fmt::format("list path '{}' fail, ec: {}", path_, std::strerror(cur_errno)));
    }
    return Status::OK();
}

Status LocalFile::ListFiles(std::vector<std::unique_ptr<LocalFile>>* file_list) const {
    CHECK_HOOK();
    file_list->clear();
    std::vector<std::string> file_names;
    PAIMON_RETURN_NOT_OK(List(&file_names));
    for (const auto& file_name : file_names) {
        PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<LocalFile> file,
                               LocalFile::Create(PathUtil::JoinPath(path_, file_name)));
        file_list->push_back(std::move(file));
    }
    return Status::OK();
}

Status LocalFile::Delete() const {
    CHECK_HOOK();
    PAIMON_ASSIGN_OR_RAISE(bool is_exist, Exists());
    if (is_exist) {
        if (::remove(path_.c_str()) != 0) {
            if (errno != ENOENT) {
                return Status::IOError(
                    fmt::format("delete path '{}' fail, ec: {}", path_, std::strerror(errno)));
            }
        }
    }
    return Status::OK();
}

Result<bool> LocalFile::Mkdir() const {
    CHECK_HOOK();
    return mkdir(path_.c_str(), 0755) == 0;
}

Result<FileStatus> LocalFile::GetFileStatus() const {
    CHECK_HOOK();
    struct stat buf;
    if (stat(path_.c_str(), &buf) < 0) {
        int32_t cur_errno = errno;
        return Status::IOError(
            fmt::format("get file '{}' status failed, ec: {}", path_, std::strerror(cur_errno)));
    }
    return FileStatus(path_, buf.st_size, S_ISDIR(buf.st_mode), buf.st_mtime * 1000);
}

Result<int64_t> LocalFile::Length() const {
    CHECK_HOOK();
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, GetFileStatus());
    return file_status.GetLen();
}

Result<int64_t> LocalFile::LastModifiedTimeMs() const {
    CHECK_HOOK();
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, GetFileStatus());
    return file_status.GetModificationTime();
}

std::unique_ptr<LocalFile> LocalFile::GetParentFile() const {
    size_t pos = path_.rfind('/');
    if (pos == std::string::npos) {
        return std::unique_ptr<LocalFile>(new LocalFile(""));
    } else {
        std::string parent_dir = path_.substr(0, pos);
        return std::unique_ptr<LocalFile>(new LocalFile(parent_dir));
    }
}

const std::string& LocalFile::GetPath() const {
    return path_;
}

Result<int64_t> LocalFile::Read(char* buffer, int64_t length, int64_t offset) {
    if (file_) {
        CHECK_HOOK();
        PAIMON_RETURN_NOT_OK(ValidateValueNonNegative(length, "read length"));
        PAIMON_RETURN_NOT_OK(ValidateValueNonNegative(offset, "read offset"));
        int32_t fd = fileno(file_);

        int64_t more = length;
        int64_t off = 0;
        int64_t ret = 0;
        while (more > 0) {
            ret = ::pread(fd, buffer + off, more, offset + off);
            if (ret == -1) {
                return Status::IOError(fmt::format("pread file '{}' fail at off {}, ec: {}", path_,
                                                   off, std::strerror(errno)));
            }
            if (ret == 0) {
                break;
            }
            more -= ret;
            off += ret;
        }
        return off;
    }
    return Status::IOError(fmt::format(
        "read file '{}' fail, can not read file which is opened fail, ec: EBADF", path_));
}

Result<int64_t> LocalFile::Read(char* buffer, int64_t length) {
    if (file_) {
        CHECK_HOOK();
        PAIMON_RETURN_NOT_OK(ValidateValueNonNegative(length, "read length"));

        int64_t more = length;
        int64_t ret = 0;
        int64_t off = 0;
        while (more > 0) {
            ret = fread(buffer + off, 1, more, file_);
            if (ferror(file_) != 0) {
                return Status::IOError(fmt::format("read file '{}' fail at off {}, ec: {}", path_,
                                                   off, std::strerror(errno)));
            }
            more -= ret;
            off += ret;
            if (feof(file_)) {
                break;
            }
        }
        return off;
    }

    return Status::IOError(fmt::format(
        "read file '{}' fail, can not read file which is opened fail, ec: EBADF", path_));
}

Result<int64_t> LocalFile::Write(const char* buffer, int64_t length) {
    if (file_) {
        CHECK_HOOK();
        PAIMON_RETURN_NOT_OK(ValidateValueNonNegative(length, "write length"));

        int64_t more = length;
        int64_t ret = 0;
        int64_t off = 0;
        while (more > 0) {
            ret = fwrite(buffer + off, 1, more, file_);
            if (ferror(file_) != 0) {
                return Status::IOError(fmt::format("write file '{}' fail at off {}, ec: {}", path_,
                                                   off, std::strerror(errno)));
            }
            if (ret == 0) {
                return Status::IOError(
                    fmt::format("write file '{}' fail at off {}, wrote zero bytes, ec: {}", path_,
                                off, std::strerror(errno)));
            }
            more -= ret;
            off += ret;
        }
        return off;
    }

    return Status::IOError(
        fmt::format("write file '{}' fail, can not write file which not opened, ec: EBADF", path_));
}

Status LocalFile::Flush() {
    if (file_) {
        CHECK_HOOK();
        int32_t ret = fflush(file_);
        if (0 == ret) {
            CHECK_HOOK();
            int32_t fd = fileno(file_);
            ret |= fsync(fd);
        }
        if (0 != ret) {
            return Status::IOError(
                fmt::format("flush '{}' fail, ec: {}", path_, std::strerror(errno)));
        }
        return Status::OK();
    }
    return Status::IOError(
        fmt::format("flush '{}' fail, can not flush file which not opened, ec: EBADF", path_));
}

Status LocalFile::OpenFile(bool is_read_file) {
    if (is_read_file) {
        PAIMON_ASSIGN_OR_RAISE(bool is_exist, Exists());
        if (!is_exist) {
            return Status::IOError(
                fmt::format("direct openFile '{}' fail, file not exist, ec: ENOENT", path_));
        }
        PAIMON_ASSIGN_OR_RAISE(bool is_dir, IsDir());
        if (is_dir) {
            return Status::IOError(fmt::format(
                "direct openFile '{}' fail, cannot open a directory, ec: EISDIR", path_));
        }
        CHECK_HOOK();
        file_ = fopen(path_.c_str(), "r");
    } else {
        CHECK_HOOK();
        file_ = fopen(path_.c_str(), "w");
    }
    if (file_ == nullptr) {
        return Status::IOError(fmt::format("open '{}' fail, ec: {}", path_, std::strerror(errno)));
    }
    return Status::OK();
}

Status LocalFile::Close() {
    if (file_) {
        CHECK_HOOK();
        if (fclose(file_) != 0) {
            file_ = nullptr;
            return Status::IOError(
                fmt::format("close '{}' fail, ec: {}", path_, std::strerror(errno)));
        }
        file_ = nullptr;
    }
    return Status::OK();
}

Status LocalFile::Seek(int64_t offset, int32_t seek_origin) {
    if (file_) {
        CHECK_HOOK();
        int32_t ret = 0;
        ret = fseek(file_, offset, seek_origin);
        if (ret != 0) {
            return Status::IOError(
                fmt::format("seek '{}' fail, ec: {}", path_, std::strerror(errno)));
        }
        return Status::OK();
    }
    return Status::IOError(
        fmt::format("seek '{}' fail, can not read file which not opened, ec: EBADF", path_));
}

Result<int64_t> LocalFile::Tell() const {
    if (file_) {
        CHECK_HOOK();
        int64_t ret = ftell(file_);
        if (ret < 0) {
            return Status::IOError(
                fmt::format("tell '{}' fail, ec: {}", path_, std::strerror(errno)));
        }
        return ret;
    }
    return Status::IOError(
        fmt::format("tell '{}' fail, can not read file which not opened, ec: EBADF", path_));
}

}  // namespace paimon
