/*
 * 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 <getopt.h>
#include <unistd.h>

#include <iostream>
#include <map>

#include <android-base/parseint.h>
#include <utils/Errors.h>
#include <vintf/VintfObject.h>
#include <vintf/parse_xml.h>
#include "utils.h"

namespace android {
namespace vintf {
namespace details {

// fake sysprops
using Properties = std::map<std::string, std::string>;

enum Option : int {
    DUMP_FILE_LIST = 1,
    ROOTDIR,
    HELP,
    PROPERTY,
    CHECK_COMPAT,
};
// command line arguments
using Args = std::multimap<Option, std::string>;

class HostFileFetcher : public FileFetcher {
   public:
    void setRootDir(const std::string& rootdir) {
        mRootDir = rootdir;
        if (!mRootDir.empty() && mRootDir.back() != '/') {
            mRootDir.push_back('/');
        }
    }
    virtual status_t fetch(const std::string& path, std::string& fetched, std::string* error) {
        return HostFileFetcher::fetchInternal(path, fetched, error);
    }
    virtual status_t fetch(const std::string& path, std::string& fetched) {
        return HostFileFetcher::fetchInternal(path, fetched, nullptr);
    }
    virtual status_t listFiles(const std::string& path, std::vector<std::string>* out,
                               std::string* error) {
        status_t status = FileFetcher::listFiles(mRootDir + path, out, error);
        std::cerr << "Debug: List '" << mRootDir << path << "': " << toString(status) << std::endl;
        return status;
    }

   private:
    status_t fetchInternal(const std::string& path, std::string& fetched, std::string* error) {
        status_t status = FileFetcher::fetchInternal(mRootDir + path, fetched, error);
        std::cerr << "Debug: Fetch '" << mRootDir << path << "': " << toString(status) << std::endl;
        return status;
    }
    static std::string toString(status_t status) {
        return status == OK ? "SUCCESS" : strerror(-status);
    }
    std::string mRootDir;
};

class PresetPropertyFetcher : public PropertyFetcher {
   public:
    std::string getProperty(const std::string& key,
                            const std::string& defaultValue) const override {
        auto it = mProps.find(key);
        if (it == mProps.end()) {
            std::cerr << "Debug: Sysprop " << key << " is missing, default to '" << defaultValue
                      << "'" << std::endl;
            return defaultValue;
        }
        std::cerr << "Debug: Sysprop " << key << "=" << it->second << std::endl;
        return it->second;
    }
    uint64_t getUintProperty(const std::string& key, uint64_t defaultValue,
                             uint64_t max) const override {
        uint64_t result;
        std::string value = getProperty(key, "");
        if (!value.empty() && android::base::ParseUint(value, &result, max)) return result;
        return defaultValue;
    }
    bool getBoolProperty(const std::string& key, bool defaultValue) const override {
        std::string value = getProperty(key, "");
        if (value == "1" || value == "true") {
            return true;
        } else if (value == "0" || value == "false") {
            return false;
        }
        return defaultValue;
    }
    void setProperties(const Properties& props) { mProps.insert(props.begin(), props.end()); }

   private:
    std::map<std::string, std::string> mProps;
};

// globals
static HostFileFetcher hostFileFetcher;
FileFetcher* gFetcher = &hostFileFetcher;

static PartitionMounter partitionMounter;
PartitionMounter* gPartitionMounter = &partitionMounter;

static ObjectFactory<RuntimeInfo> runtimeInfoFactory;
ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory;

static PresetPropertyFetcher hostPropertyFetcher;
const PropertyFetcher& getPropertyFetcher() {
    return hostPropertyFetcher;
}

// helper functions
template <typename T>
std::unique_ptr<T> readObject(const std::string& path, const XmlConverter<T>& converter) {
    std::string xml;
    std::string error;
    status_t err = details::gFetcher->fetch(path, xml, &error);
    if (err != OK) {
        std::cerr << "Error: Cannot read '" << path << "' (" << strerror(-err) << "): " << error
                  << std::endl;
        return nullptr;
    }
    auto ret = std::make_unique<T>();
    if (!converter(ret.get(), xml, &error)) {
        std::cerr << "Error: Cannot parse '" << path << "': " << error << std::endl;
        return nullptr;
    }
    return ret;
}

int checkCompatibilityForFiles(const std::string& manifestPath, const std::string& matrixPath) {
    auto manifest = readObject(manifestPath, gHalManifestConverter);
    auto matrix = readObject(matrixPath, gCompatibilityMatrixConverter);
    if (manifest == nullptr || matrix == nullptr) {
        return -1;
    }

    std::string error;
    if (!manifest->checkCompatibility(*matrix, &error)) {
        std::cerr << "Error: Incompatible: " << error << std::endl;
        std::cout << "false" << std::endl;
        return 1;
    }

    std::cout << "true" << std::endl;
    return 0;
}

Args parseArgs(int argc, char** argv) {
    int longOptFlag;
    int optionIndex;
    Args ret;
    std::vector<struct option> longopts{
        {"dump-file-list", no_argument, &longOptFlag, DUMP_FILE_LIST},
        {"rootdir", required_argument, &longOptFlag, ROOTDIR},
        {"help", no_argument, &longOptFlag, HELP},
        {"property", required_argument, &longOptFlag, PROPERTY},
        {"check-compat", no_argument, &longOptFlag, CHECK_COMPAT},
        {0, 0, 0, 0}};
    std::map<int, Option> shortopts{
        {'h', HELP}, {'D', PROPERTY}, {'c', CHECK_COMPAT},
    };
    for (;;) {
        int c = getopt_long(argc, argv, "hcD:", longopts.data(), &optionIndex);
        if (c == -1) {
            break;
        }
        std::string argValue = optarg ? optarg : std::string{};
        if (c == 0) {
            ret.emplace(static_cast<Option>(longOptFlag), std::move(argValue));
        } else {
            ret.emplace(shortopts[c], std::move(argValue));
        }
    }
    if (optind < argc) {
        // see non option
        std::cerr << "unrecognized option `" << argv[optind] << "'" << std::endl;
        return {{HELP, ""}};
    }
    return ret;
}

template <typename T>
Properties getProperties(const T& args) {
    Properties ret;
    for (const auto& arg : args) {
        auto pos = arg.find('=');
        auto key = arg.substr(0, pos);
        auto value = pos == std::string::npos ? std::string{} : arg.substr(pos + 1);
        ret[key] = value;
    }
    return ret;
}

int usage(const char* me) {
    std::cerr
        << me << ": check VINTF metadata." << std::endl
        << "    Options:" << std::endl
        << "        --dump-file-list: Dump a list of directories / files on device" << std::endl
        << "                that is required to be used by --check-compat." << std::endl
        << "        -c, --check-compat: check compatibility for files under the root" << std::endl
        << "                directory specified by --root-dir." << std::endl
        << "        --rootdir=<dir>: specify root directory for all metadata." << std::endl
        << "        -D, --property <key>=<value>: specify sysprops." << std::endl
        << "        --help: show this message." << std::endl
        << std::endl
        << "    Example:" << std::endl
        << "        # Get the list of required files." << std::endl
        << "        " << me << " --dump-file-list > /tmp/files.txt" << std::endl
        << "        # Pull from ADB, or use your own command to extract files from images"
        << std::endl
        << "        ROOTDIR=/tmp/device/" << std::endl
        << "        cat /tmp/files.txt | xargs -I{} bash -c \"mkdir -p $ROOTDIR`dirname {}` && adb "
           "pull {} $ROOTDIR{}\""
        << std::endl
        << "        # Check compatibility." << std::endl
        << "        " << me << " --check-compat --rootdir=$ROOTDIR \\" << std::endl
        << "            --property ro.product.first_api_level=`adb shell getprop "
           "ro.product.first_api_level` \\"
        << std::endl
        << "            --property ro.boot.product.hardware.sku=`adb shell getprop "
           "ro.boot.product.hardware.sku`"
        << std::endl;
    return 1;
}

int checkAllFiles(const std::string& rootdir, const Properties& props, std::string* error) {
    hostFileFetcher.setRootDir(rootdir);
    hostPropertyFetcher.setProperties(props);

    return VintfObject::CheckCompatibility({} /* packageInfo */, error, DISABLE_RUNTIME_INFO);
}

}  // namespace details
}  // namespace vintf
}  // namespace android

int main(int argc, char** argv) {
    using namespace android::vintf;
    using namespace android::vintf::details;
    // legacy usage: check_vintf <manifest.xml> <matrix.xml>
    if (argc == 3) {
        int ret = checkCompatibilityForFiles(argv[1], argv[2]);
        if (ret >= 0) return ret;
    }

    Args args = parseArgs(argc, argv);

    if (!iterateValues(args, HELP).empty()) {
        return usage(argv[0]);
    }

    if (!iterateValues(args, DUMP_FILE_LIST).empty()) {
        for (const auto& file : dumpFileList()) {
            std::cout << file << std::endl;
        }
        return 0;
    }

    auto rootdirs = iterateValues(args, ROOTDIR);
    auto properties = getProperties(iterateValues(args, PROPERTY));

    auto checkCompat = iterateValues(args, CHECK_COMPAT);
    if (!checkCompat.empty()) {
        if (rootdirs.empty()) {
            std::cerr << "Missing --rootdir option." << std::endl;
            return usage(argv[0]);
        }
        int ret = COMPATIBLE;
        for (const auto& rootdir : rootdirs) {
            std::cerr << "Debug: checking files under " << rootdir << "..." << std::endl;
            std::string error;
            int compat = checkAllFiles(rootdir, properties, &error);
            std::cerr << "Debug: files under " << rootdir
                      << (compat == COMPATIBLE
                              ? " is compatible"
                              : compat == INCOMPATIBLE ? " are incompatible"
                                                       : (" has encountered an error: " + error))
                      << std::endl;
        }
        if (ret == COMPATIBLE) {
            std::cout << "true" << std::endl;
        }
        return ret;
    }

    return usage(argv[0]);
}
