/*
 * 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 <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 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
