/*
 * Copyright (C) 2015 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 "util/Files.h"
#include "util/Util.h"

#include <algorithm>
#include <android-base/file.h>
#include <cerrno>
#include <cstdio>
#include <dirent.h>
#include <string>
#include <sys/stat.h>

#ifdef _WIN32
// Windows includes.
#include <direct.h>
#endif

namespace aapt {
namespace file {

FileType getFileType(const StringPiece& path) {
    struct stat sb;
    if (stat(path.data(), &sb) < 0) {
        if (errno == ENOENT || errno == ENOTDIR) {
            return FileType::kNonexistant;
        }
        return FileType::kUnknown;
    }

    if (S_ISREG(sb.st_mode)) {
        return FileType::kRegular;
    } else if (S_ISDIR(sb.st_mode)) {
        return FileType::kDirectory;
    } else if (S_ISCHR(sb.st_mode)) {
        return FileType::kCharDev;
    } else if (S_ISBLK(sb.st_mode)) {
        return FileType::kBlockDev;
    } else if (S_ISFIFO(sb.st_mode)) {
        return FileType::kFifo;
#if defined(S_ISLNK)
    } else if (S_ISLNK(sb.st_mode)) {
        return FileType::kSymlink;
#endif
#if defined(S_ISSOCK)
    } else if (S_ISSOCK(sb.st_mode)) {
        return FileType::kSocket;
#endif
    } else {
        return FileType::kUnknown;
    }
}

std::vector<std::string> listFiles(const StringPiece& root, std::string* outError) {
    DIR* dir = opendir(root.data());
    if (dir == nullptr) {
        if (outError) {
            std::stringstream errorStr;
            errorStr << "unable to open file: " << strerror(errno);
            *outError = errorStr.str();
        }
        return {};
    }

    std::vector<std::string> files;
    dirent* entry;
    while ((entry = readdir(dir))) {
        files.emplace_back(entry->d_name);
    }

    closedir(dir);
    return files;
}

inline static int mkdirImpl(const StringPiece& path) {
#ifdef _WIN32
    return _mkdir(path.toString().c_str());
#else
    return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
#endif
}

bool mkdirs(const StringPiece& path) {
    const char* start = path.begin();
    const char* end = path.end();
    for (const char* current = start; current != end; ++current) {
        if (*current == sDirSep && current != start) {
            StringPiece parentPath(start, current - start);
            int result = mkdirImpl(parentPath);
            if (result < 0 && errno != EEXIST) {
                return false;
            }
        }
    }
    return mkdirImpl(path) == 0 || errno == EEXIST;
}

StringPiece getStem(const StringPiece& path) {
    const char* start = path.begin();
    const char* end = path.end();
    for (const char* current = end - 1; current != start - 1; --current) {
        if (*current == sDirSep) {
            return StringPiece(start, current - start);
        }
    }
    return {};
}

StringPiece getFilename(const StringPiece& path) {
    const char* end = path.end();
    const char* lastDirSep = path.begin();
    for (const char* c = path.begin(); c != end; ++c) {
        if (*c == sDirSep) {
            lastDirSep = c + 1;
        }
    }
    return StringPiece(lastDirSep, end - lastDirSep);
}

StringPiece getExtension(const StringPiece& path) {
    StringPiece filename = getFilename(path);
    const char* const end = filename.end();
    const char* c = std::find(filename.begin(), end, '.');
    if (c != end) {
        return StringPiece(c, end - c);
    }
    return {};
}

void appendPath(std::string* base, StringPiece part) {
    assert(base);
    const bool baseHasTrailingSep = (!base->empty() && *(base->end() - 1) == sDirSep);
    const bool partHasLeadingSep = (!part.empty() && *(part.begin()) == sDirSep);
    if (baseHasTrailingSep && partHasLeadingSep) {
        // Remove the part's leading sep
        part = part.substr(1, part.size() - 1);
    } else if (!baseHasTrailingSep && !partHasLeadingSep) {
        // None of the pieces has a separator.
        *base += sDirSep;
    }
    base->append(part.data(), part.size());
}

std::string packageToPath(const StringPiece& package) {
    std::string outPath;
    for (StringPiece part : util::tokenize<char>(package, '.')) {
        appendPath(&outPath, part);
    }
    return outPath;
}

Maybe<android::FileMap> mmapPath(const StringPiece& path, std::string* outError) {
    std::unique_ptr<FILE, decltype(fclose)*> f = { fopen(path.data(), "rb"), fclose };
    if (!f) {
        if (outError) *outError = strerror(errno);
        return {};
    }

    int fd = fileno(f.get());

    struct stat fileStats = {};
    if (fstat(fd, &fileStats) != 0) {
        if (outError) *outError = strerror(errno);
        return {};
    }

    android::FileMap fileMap;
    if (fileStats.st_size == 0) {
        // mmap doesn't like a length of 0. Instead we return an empty FileMap.
        return std::move(fileMap);
    }

    if (!fileMap.create(path.data(), fd, 0, fileStats.st_size, true)) {
        if (outError) *outError = strerror(errno);
        return {};
    }
    return std::move(fileMap);
}

bool appendArgsFromFile(const StringPiece& path, std::vector<std::string>* outArgList,
                        std::string* outError) {
    std::string contents;
    if (!android::base::ReadFileToString(path.toString(), &contents)) {
        if (outError) *outError = "failed to read argument-list file";
        return false;
    }

    for (StringPiece line : util::tokenize<char>(contents, ' ')) {
        line = util::trimWhitespace(line);
        if (!line.empty()) {
            outArgList->push_back(line.toString());
        }
    }
    return true;
}

bool FileFilter::setPattern(const StringPiece& pattern) {
    mPatternTokens = util::splitAndLowercase(pattern, ':');
    return true;
}

bool FileFilter::operator()(const std::string& filename, FileType type) const {
    if (filename == "." || filename == "..") {
        return false;
    }

    const char kDir[] = "dir";
    const char kFile[] = "file";
    const size_t filenameLen = filename.length();
    bool chatty = true;
    for (const std::string& token : mPatternTokens) {
        const char* tokenStr = token.c_str();
        if (*tokenStr == '!') {
            chatty = false;
            tokenStr++;
        }

        if (strncasecmp(tokenStr, kDir, sizeof(kDir)) == 0) {
            if (type != FileType::kDirectory) {
                continue;
            }
            tokenStr += sizeof(kDir);
        }

        if (strncasecmp(tokenStr, kFile, sizeof(kFile)) == 0) {
            if (type != FileType::kRegular) {
                continue;
            }
            tokenStr += sizeof(kFile);
        }

        bool ignore = false;
        size_t n = strlen(tokenStr);
        if (*tokenStr == '*') {
            // Math suffix.
            tokenStr++;
            n--;
            if (n <= filenameLen) {
                ignore = strncasecmp(tokenStr, filename.c_str() + filenameLen - n, n) == 0;
            }
        } else if (n > 1 && tokenStr[n - 1] == '*') {
            // Match prefix.
            ignore = strncasecmp(tokenStr, filename.c_str(), n - 1) == 0;
        } else {
            ignore = strcasecmp(tokenStr, filename.c_str()) == 0;
        }

        if (ignore) {
            if (chatty) {
                mDiag->warn(DiagMessage() << "skipping "
                            << (type == FileType::kDirectory ? "dir '" : "file '")
                            << filename << "' due to ignore pattern '"
                            << token << "'");
            }
            return false;
        }
    }
    return true;
}

} // namespace file
} // namespace aapt
