/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#include "path.h"

#include <android-base/strings.h>
#include <android-base/logging.h>

#include <algorithm>
#include <iterator>
#include <limits>
#include <memory>

#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

using namespace std::literals;

namespace android::incremental::path {

bool PathCharsLess::operator()(char l, char r) const {
    int ll = l == '/' ? std::numeric_limits<char>::min() - 1 : l;
    int rr = r == '/' ? std::numeric_limits<char>::min() - 1 : r;
    return ll < rr;
}

bool PathLess::operator()(std::string_view l, std::string_view r) const {
    return std::lexicographical_compare(std::begin(l), std::end(l), std::begin(r), std::end(r),
                                        PathCharsLess());
}

static void preparePathComponent(std::string_view path, bool trimFront) {
    if (trimFront) {
        while (!path.empty() && path.front() == '/') {
            path.remove_prefix(1);
        }
    }
    while (!path.empty() && path.back() == '/') {
        path.remove_suffix(1);
    }
}

void details::append_next_path(std::string& target, std::string_view path) {
    preparePathComponent(path, true);
    if (path.empty()) {
        return;
    }
    if (!target.empty() && !target.ends_with('/')) {
        target.push_back('/');
    }
    target += path;
}

std::string_view relativize(std::string_view parent, std::string_view nested) {
    if (!nested.starts_with(parent)) {
        return nested;
    }
    if (nested.size() == parent.size()) {
        return {};
    }
    if (nested[parent.size()] != '/') {
        return nested;
    }
    auto relative = nested.substr(parent.size());
    while (relative.front() == '/') {
        relative.remove_prefix(1);
    }
    return relative;
}

bool isAbsolute(std::string_view path) {
    return !path.empty() && path[0] == '/';
}

std::string normalize(std::string_view path) {
    if (path.empty()) {
        return {};
    }
    if (path.starts_with("../"sv)) {
        return {};
    }

    std::string result;
    if (isAbsolute(path)) {
        path.remove_prefix(1);
    } else {
        char buffer[PATH_MAX];
        if (!::getcwd(buffer, sizeof(buffer))) {
            return {};
        }
        result += buffer;
    }

    size_t start = 0;
    size_t end = 0;
    for (; end != path.npos; start = end + 1) {
        end = path.find('/', start);
        // Next component, excluding the separator
        auto part = path.substr(start, end - start);
        if (part.empty() || part == "."sv) {
            continue;
        }
        if (part == ".."sv) {
            if (result.empty()) {
                return {};
            }
            auto lastPos = result.rfind('/');
            if (lastPos == result.npos) {
                result.clear();
            } else {
                result.resize(lastPos);
            }
            continue;
        }
        result += '/';
        result += part;
    }

    return result;
}

std::string_view basename(std::string_view path) {
    if (path.empty()) {
        return {};
    }
    if (path == "/"sv) {
        return "/"sv;
    }
    auto pos = path.rfind('/');
    while (!path.empty() && pos == path.size() - 1) {
        path.remove_suffix(1);
        pos = path.rfind('/');
    }
    if (pos == path.npos) {
        return path.empty() ? "/"sv : path;
    }
    return path.substr(pos + 1);
}

std::string_view dirname(std::string_view path) {
    if (path.empty()) {
        return {};
    }
    if (path == "/"sv) {
        return "/"sv;
    }
    const auto pos = path.rfind('/');
    if (pos == 0) {
        return "/"sv;
    }
    if (pos == path.npos) {
        return "."sv;
    }
    return path.substr(0, pos);
}

details::CStrWrapper::CStrWrapper(std::string_view sv) {
    if (sv[sv.size()] == '\0') {
        mCstr = sv.data();
    } else {
        mCopy.emplace(sv);
        mCstr = mCopy->c_str();
    }
}

std::optional<bool> isEmptyDir(std::string_view dir) {
    const auto d = std::unique_ptr<DIR, decltype(&::closedir)>{::opendir(c_str(dir)), ::closedir};
    if (!d) {
        if (errno == EPERM || errno == EACCES) {
            return std::nullopt;
        }
        return false;
    }
    while (auto entry = ::readdir(d.get())) {
        if (entry->d_type != DT_DIR) {
            return false;
        }
        if (entry->d_name != "."sv && entry->d_name != ".."sv) {
            return false;
        }
    }
    return true;
}

bool startsWith(std::string_view path, std::string_view prefix) {
    if (!base::StartsWith(path, prefix)) {
        return false;
    }
    return path.size() == prefix.size() || path[prefix.size()] == '/';
}

} // namespace android::incremental::path
