/*
 * Copyright (C) 2017 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 "Hash.h"

#include <fstream>
#include <iomanip>
#include <map>
#include <regex>
#include <sstream>

#include <android-base/logging.h>
#include <openssl/sha.h>

namespace android {

const Hash &Hash::getHash(const std::string &path) {
    static std::map<std::string, Hash> hashes;

    auto it = hashes.find(path);

    if (hashes.find(path) == hashes.end()) {
        it = hashes.insert(it, {path, Hash(path)});
    }

    return it->second;
}

static std::vector<uint8_t> sha256File(const std::string &path) {
    std::ifstream stream(path);
    std::stringstream fileStream;
    fileStream << stream.rdbuf();
    std::string fileContent = fileStream.str();

    std::vector<uint8_t> ret = std::vector<uint8_t>(SHA256_DIGEST_LENGTH);

    SHA256(reinterpret_cast<const uint8_t *>(fileContent.c_str()),
            fileContent.size(), ret.data());

    return ret;
}

Hash::Hash(const std::string &path)
  : mPath(path),
    mHash(sha256File(path)) {}

std::string Hash::hexString(const std::vector<uint8_t> &hash) {
    std::ostringstream s;
    s << std::hex << std::setfill('0');
    for (uint8_t i : hash) {
        s << std::setw(2) << static_cast<int>(i);
    }
    return s.str();
}

std::string Hash::hexString() const {
    return hexString(mHash);
}

const std::vector<uint8_t> &Hash::raw() const {
    return mHash;
}

const std::string &Hash::getPath() const {
    return mPath;
}

#define HASH "([0-9a-f]+)"
#define FQNAME "([^\\s]+)"
#define SPACES " +"
#define MAYBE_SPACES " *"
#define OPTIONAL_COMMENT "(?:#.*)?"
static const std::regex kHashLine(
    "(?:"
        MAYBE_SPACES HASH SPACES FQNAME MAYBE_SPACES
    ")?"
    OPTIONAL_COMMENT);

struct HashFile {
    static const HashFile *parse(const std::string &path, std::string *err) {
        static std::map<std::string, HashFile*> hashfiles;
        auto it = hashfiles.find(path);

        if (it == hashfiles.end()) {
            it = hashfiles.insert(it, {path, readHashFile(path, err)});
        }

        return it->second;
    }

    std::vector<std::string> lookup(const std::string &fqName) const {
        auto it = hashes.find(fqName);

        if (it == hashes.end()) {
            return {};
        }

        return it->second;
    }

private:
    static HashFile *readHashFile(const std::string &path, std::string *err) {
        std::ifstream stream(path);
        if (!stream) {
            return nullptr;
        }

        HashFile *file = new HashFile();
        file->path = path;

        std::string line;
        while(std::getline(stream, line)) {
            std::smatch match;
            bool valid = std::regex_match(line, match, kHashLine);

            if (!valid) {
                *err = "Error reading line from " + path + ": " + line;
                delete file;
                return nullptr;
            }

            CHECK_EQ(match.size(), 3u);

            std::string hash = match.str(1);
            std::string fqName = match.str(2);

            if (hash.size() == 0 && fqName.size() == 0) {
                continue;
            }

            if (hash.size() == 0 || fqName.size() == 0) {
                *err = "Hash or fqName empty on " + path + ": " + line;
                delete file;
                return nullptr;
            }

            file->hashes[fqName].push_back(hash);
        }
        return file;
    }

    std::string path;
    std::map<std::string,std::vector<std::string>> hashes;
};

//static
std::vector<std::string> Hash::lookupHash(const std::string &path,
                                          const std::string &interfaceName,
                                          std::string *err) {
    *err = "";
    const HashFile *file = HashFile::parse(path, err);

    if (file == nullptr || err->size() > 0) {
        return {};
    }

    return file->lookup(interfaceName);
}

}  // android
