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

#include <fstream>
#include <iostream>
#include <unordered_map>
#include <sstream>
#include <string>

#include <vintf/parse_string.h>
#include <vintf/parse_xml.h>

namespace android {
namespace vintf {

/**
 * Slurps the device manifest file and add build time flag to it.
 */
class AssembleVintf {
public:
    template<typename T>
    static bool getFlag(const std::string& key, T* value) {
        const char *envValue = getenv(key.c_str());
        if (envValue == NULL) {
            std::cerr << "Required " << key << " flag." << std::endl;
            return false;
        }

        if (!parse(envValue, value)) {
            std::cerr << "Cannot parse " << envValue << "." << std::endl;
            return false;
        }
        return true;
    }

    static std::string read(std::basic_istream<char>& is) {
        std::stringstream ss;
        ss << is.rdbuf();
        return ss.str();
    }

    std::basic_ostream<char>& out() const {
        return mOutFileRef == nullptr ? std::cout : *mOutFileRef;
    }

    bool assembleHalManifest(HalManifest* halManifest) {
        std::string error;

        if (halManifest->mType == SchemaType::DEVICE) {
            if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) {
                return false;
            }
        }

        if (mOutputMatrix) {
            CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix();
            if (!halManifest->checkCompatibility(generatedMatrix, &error)) {
                std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error
                          << std::endl;
            }
            out() << "<!-- \n"
                     "    Autogenerated skeleton compatibility matrix. \n"
                     "    Use with caution. Modify it to suit your needs.\n"
                     "    All HALs are set to optional.\n"
                     "    Many entries other than HALs are zero-filled and\n"
                     "    require human attention. \n"
                     "-->\n"
                  << gCompatibilityMatrixConverter(generatedMatrix);
        } else {
            out() << gHalManifestConverter(*halManifest);
        }
        out().flush();

        if (mCheckFile.is_open()) {
            CompatibilityMatrix checkMatrix;
            if (!gCompatibilityMatrixConverter(&checkMatrix, read(mCheckFile))) {
                std::cerr << "Cannot parse check file as a compatibility matrix: "
                          << gCompatibilityMatrixConverter.lastError() << std::endl;
                return false;
            }
            if (!halManifest->checkCompatibility(checkMatrix, &error)) {
                std::cerr << "Not compatible: " << error << std::endl;
                return false;
            }
        }

        return true;
    }

    bool assembleCompatibilityMatrix(CompatibilityMatrix* matrix) {
        std::string error;

        KernelSepolicyVersion kernelSepolicyVers;
        Version sepolicyVers;
        if (matrix->mType == SchemaType::FRAMEWORK) {
            if (!getFlag("BOARD_SEPOLICY_VERS", &sepolicyVers)) {
                return false;
            }
            if (!getFlag("POLICYVERS", &kernelSepolicyVers)) {
                return false;
            }
            matrix->framework.mSepolicy =
                Sepolicy(kernelSepolicyVers, {{sepolicyVers.majorVer, sepolicyVers.minorVer}});

            Version avbMetaVersion;
            if (!getFlag("FRAMEWORK_VBMETA_VERSION", &avbMetaVersion)) {
                return false;
            }
            matrix->framework.mAvbMetaVersion = avbMetaVersion;
        }
        out() << gCompatibilityMatrixConverter(*matrix);
        out().flush();

        if (mCheckFile.is_open()) {
            HalManifest checkManifest;
            if (!gHalManifestConverter(&checkManifest, read(mCheckFile))) {
                std::cerr << "Cannot parse check file as a HAL manifest: "
                          << gHalManifestConverter.lastError() << std::endl;
                return false;
            }
            if (!checkManifest.checkCompatibility(*matrix, &error)) {
                std::cerr << "Not compatible: " << error << std::endl;
                return false;
            }
        }

        return true;
    }

    enum AssembleStatus { SUCCESS, FAIL_AND_EXIT, TRY_NEXT };
    template <typename Schema, typename AssembleFunc>
    AssembleStatus tryAssemble(const XmlConverter<Schema>& converter, const std::string& schemaName,
                               AssembleFunc assemble) {
        Schema schema;
        if (!converter(&schema, read(mInFiles.front()))) {
            return TRY_NEXT;
        }
        auto firstType = schema.type();
        for (auto it = mInFiles.begin() + 1; it != mInFiles.end(); ++it) {
            Schema additionalSchema;
            if (!converter(&additionalSchema, read(*it))) {
                std::cerr << "File \"" << mInFilePaths[std::distance(mInFiles.begin(), it)]
                          << "\" is not a valid " << firstType << " " << schemaName
                          << " (but the first file is a valid " << firstType << " " << schemaName
                          << "). Error: " << converter.lastError() << std::endl;
                return FAIL_AND_EXIT;
            }
            if (additionalSchema.type() != firstType) {
                std::cerr << "File \"" << mInFilePaths[std::distance(mInFiles.begin(), it)]
                          << "\" is a " << additionalSchema.type() << " " << schemaName
                          << " (but a " << firstType << " " << schemaName << " is expected)."
                          << std::endl;
                return FAIL_AND_EXIT;
            }
            schema.addAll(std::move(additionalSchema));
        }
        return assemble(&schema) ? SUCCESS : FAIL_AND_EXIT;
    }

    bool assemble() {
        using std::placeholders::_1;
        if (mInFiles.empty()) {
            std::cerr << "Missing input file." << std::endl;
            return false;
        }

        auto status = tryAssemble(gHalManifestConverter, "manifest",
                                  std::bind(&AssembleVintf::assembleHalManifest, this, _1));
        if (status == SUCCESS) return true;
        if (status == FAIL_AND_EXIT) return false;

        resetInFiles();

        status = tryAssemble(gCompatibilityMatrixConverter, "compatibility matrix",
                             std::bind(&AssembleVintf::assembleCompatibilityMatrix, this, _1));
        if (status == SUCCESS) return true;
        if (status == FAIL_AND_EXIT) return false;

        std::cerr << "Input file has unknown format." << std::endl
                  << "Error when attempting to convert to manifest: "
                  << gHalManifestConverter.lastError() << std::endl
                  << "Error when attempting to convert to compatibility matrix: "
                  << gCompatibilityMatrixConverter.lastError() << std::endl;
        return false;
    }

    bool openOutFile(const char* path) {
        mOutFileRef = std::make_unique<std::ofstream>();
        mOutFileRef->open(path);
        return mOutFileRef->is_open();
    }

    bool openInFile(const char* path) {
        mInFilePaths.push_back(path);
        mInFiles.push_back({});
        mInFiles.back().open(path);
        return mInFiles.back().is_open();
    }

    bool openCheckFile(const char* path) {
        mCheckFile.open(path);
        return mCheckFile.is_open();
    }

    void resetInFiles() {
        for (auto& inFile : mInFiles) {
            inFile.clear();
            inFile.seekg(0);
        }
    }

    void setOutputMatrix() { mOutputMatrix = true; }

   private:
    std::vector<std::string> mInFilePaths;
    std::vector<std::ifstream> mInFiles;
    std::unique_ptr<std::ofstream> mOutFileRef;
    std::ifstream mCheckFile;
    bool mOutputMatrix = false;
};

}  // namespace vintf
}  // namespace android

void help() {
    std::cerr << "assemble_vintf: Checks if a given manifest / matrix file is valid and \n"
                 "    fill in build-time flags into the given file.\n"
                 "assemble_vintf -h\n"
                 "               Display this help text.\n"
                 "assemble_vintf -i <input file>[:<input file>[...]] [-o <output file>] [-m]\n"
                 "               [-c [<check file>]]\n"
                 "               Fill in build-time flags into the given file.\n"
                 "    -i <input file>[:<input file>[...]]\n"
                 "               A list of input files. Format is automatically detected for the\n"
                 "               first file, and the remaining files must have the same format.\n"
                 "               Files other than the first file should only have <hal> defined;\n"
                 "               other entries are ignored.\n"
                 "    -o <output file>\n"
                 "               Optional output file. If not specified, write to stdout.\n"
                 "    -m\n"
                 "               a compatible compatibility matrix is\n"
                 "               generated instead; for example, given a device manifest,\n"
                 "               a framework compatibility matrix is generated. This flag\n"
                 "               is ignored when input is a compatibility matrix.\n"
                 "    -c [<check file>]\n"
                 "               After writing the output file, check compatibility between\n"
                 "               output file and check file.\n"
                 "               If -c is set but the check file is not specified, a warning\n"
                 "               message is written to stderr. Return 0.\n"
                 "               If the check file is specified but is not compatible, an error\n"
                 "               message is written to stderr. Return 1.\n";
}

int main(int argc, char **argv) {
    const struct option longopts[] = {{0, 0, 0, 0}};

    std::string outFilePath;
    ::android::vintf::AssembleVintf assembleVintf;
    int res;
    int optind;
    while ((res = getopt_long(argc, argv, "hi:o:mc:", longopts, &optind)) >= 0) {
        switch (res) {
            case 'i': {
                char* inFilePath = strtok(optarg, ":");
                while (inFilePath != NULL) {
                    if (!assembleVintf.openInFile(inFilePath)) {
                        std::cerr << "Failed to open " << optarg << std::endl;
                        return 1;
                    }
                    inFilePath = strtok(NULL, ":");
                }
            } break;

            case 'o': {
                outFilePath = optarg;
                if (!assembleVintf.openOutFile(optarg)) {
                    std::cerr << "Failed to open " << optarg << std::endl;
                    return 1;
                }
            } break;

            case 'm': {
                assembleVintf.setOutputMatrix();
            } break;

            case 'c': {
                if (strlen(optarg) != 0) {
                    if (!assembleVintf.openCheckFile(optarg)) {
                        std::cerr << "Failed to open " << optarg << std::endl;
                        return 1;
                    }
                } else {
                    std::cerr << "WARNING: no compatibility check is done on "
                              << (outFilePath.empty() ? "output" : outFilePath) << std::endl;
                }
            } break;

            case 'h':
            default: {
                help();
                return 1;
            } break;
        }
    }

    bool success = assembleVintf.assemble();

    return success ? 0 : 1;
}

