/*
 * 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 trimAll) {
    // need to check for double front slash as a single one has a separate meaning in front
    while (!path.empty() && path.front() == '/' &&
           (trimAll || (path.size() > 1 && path[1] == '/'))) {
        path.remove_prefix(1);
    }
    // for the back we don't care about double-vs-single slash difference
    while (path.size() > !trimAll && path.back() == '/') {
        path.remove_suffix(1);
    }
}

void details::append_next_path(std::string& target, std::string_view path) {
    preparePathComponent(path, !target.empty());
    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) {
    auto is_string_view_nul_terminated = [](std::string_view sv) {
        // NOTE(ag/38334313): `sv.data()[sv.size()]` is used instead of
        // `sv[sv.size()]` to avoid libcxx hardening checks. It's required that
        // users only pass `string_view`s here that are constructed from
        // underlying, nul-terminated C strings, and it's required that users
        // not pass `string_view`s with nul characters embedded in them.
        // Hence, reaching one past the end is always safe.
        return sv.data()[sv.size()] == '\0';
    };

    if (sv.empty()) {
        mCstr = "";
    } else if (is_string_view_nul_terminated(sv)) {
        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
