/*
 * 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 "CompatibilityMatrix.h"

#include <iostream>
#include <utility>

#include <android-base/logging.h>
#include <android-base/strings.h>

#include "parse_string.h"
#include "parse_xml.h"
#include "utils.h"

namespace android {
namespace vintf {

using details::mergeField;

bool CompatibilityMatrix::add(MatrixHal&& halToAdd, std::string*) {
    CHECK(addInternal(std::move(halToAdd)) != nullptr);
    return true;
}

bool CompatibilityMatrix::addAllHals(CompatibilityMatrix* other, std::string*) {
    std::string internalError;
    for (auto& pair : other->mHals) {
        CHECK(add(std::move(pair.second), &internalError)) << internalError;
    }
    other->mHals.clear();
    return true;
}

bool CompatibilityMatrix::addKernel(MatrixKernel&& kernel, std::string* error) {
    if (mType != SchemaType::FRAMEWORK) {
        if (error) {
            *error = "Cannot add <kernel> to a " + to_string(mType) + " compatibility matrix.";
        }
        return false;
    }

    if (kernel.getSourceMatrixLevel() == Level::UNSPECIFIED) {
        kernel.setSourceMatrixLevel(level());
    }

    auto it = framework.mKernels.begin();
    for (; it != framework.mKernels.end(); ++it) {
        if (it->getSourceMatrixLevel() != kernel.getSourceMatrixLevel()) {
            continue;
        }
        if (it->minLts() == kernel.minLts()) {
            break;
        }
        if (it->minLts().dropMinor() == kernel.minLts().dropMinor()) {
            if (error) {
                *error = "Kernel version mismatch; for level " +
                         to_string(kernel.getSourceMatrixLevel()) + ", cannot add " +
                         to_string(kernel.minLts()) + " because " + to_string(it->minLts()) +
                         " was added.";
            }
            return false;
        }
    }

    bool seenVersion = it != framework.mKernels.end();

    if (seenVersion) {
        // If no conditions, must be the first among the same minLts
        // because O libvintf only checks the first <kernel> tag that version matches.
        if (kernel.conditions().empty()) {
            // Found first <kernel> with the same minLts.
            // Append config if it does not have <condition>s, else error.
            if (it->conditions().empty()) {
                const auto& configs = kernel.configs();
                it->mConfigs.insert(it->mConfigs.end(), configs.begin(), configs.end());
            } else {
                if (error) {
                    *error =
                        "Base compatibility matrix has <condition> for the first <kernel> "
                        "with minlts " +
                        to_string(kernel.minLts()) + " for unknown reason.";
                }
                return false;
            }
            return true;
        }
    } else {
        // First <kernel> of a minLts must not have <condition>'s for backwards compatibility
        // with O libvintf.
        if (!kernel.conditions().empty()) {
            framework.mKernels.push_back(MatrixKernel(KernelVersion{kernel.minLts()}, {}));
        }
    }

    framework.mKernels.push_back(std::move(kernel));
    return true;
}

SchemaType CompatibilityMatrix::type() const {
    return mType;
}

Level CompatibilityMatrix::level() const {
    return mLevel;
}

status_t CompatibilityMatrix::fetchAllInformation(const FileSystem* fileSystem,
                                                  const std::string& path, std::string* error) {
    return details::fetchAllInformation(fileSystem, path, this, error);
}

std::string CompatibilityMatrix::getXmlSchemaPath(const std::string& xmlFileName,
                                                  const Version& version) const {
    using std::literals::string_literals::operator""s;
    auto range = getXmlFiles(xmlFileName);
    for (auto it = range.first; it != range.second; ++it) {
        const MatrixXmlFile& matrixXmlFile = it->second;
        if (matrixXmlFile.versionRange().contains(version)) {
            if (!matrixXmlFile.overriddenPath().empty()) {
                return matrixXmlFile.overriddenPath();
            }
            return "/"s + (type() == SchemaType::DEVICE ? "vendor" : "system") + "/etc/" +
                   xmlFileName + "_V" + std::to_string(matrixXmlFile.versionRange().majorVer) +
                   "_" + std::to_string(matrixXmlFile.versionRange().maxMinor) + "." +
                   to_string(matrixXmlFile.format());
        }
    }
    return "";
}

// Split existingHal into a HAL that contains only interface/instance and a HAL
// that does not contain it. Return the HAL that contains only interface/instance.
// - Return nullptr if existingHal does not contain interface/instance
// - Return existingHal if existingHal contains only interface/instance
// - Remove interface/instance from existingHal, and return a new MatrixHal (that is added
//   to "this") that contains only interface/instance.
MatrixHal* CompatibilityMatrix::splitInstance(MatrixHal* existingHal, const std::string& interface,
                                              const std::string& instanceOrPattern, bool isRegex) {
    bool found = false;
    bool foundOthers = false;
    existingHal->forEachInstance([&](const auto& matrixInstance) {
        bool interfaceMatch = matrixInstance.interface() == interface;
        bool instanceMatch = false;
        if (matrixInstance.isRegex() && isRegex) {
            instanceMatch = (matrixInstance.regexPattern() == instanceOrPattern);
        } else if (!matrixInstance.isRegex() && !isRegex) {
            instanceMatch = (matrixInstance.exactInstance() == instanceOrPattern);
        }

        bool match = interfaceMatch && instanceMatch;

        found |= match;
        foundOthers |= (!match);

        return !found || !foundOthers;
    });

    if (!found) {
        return nullptr;
    }

    if (!foundOthers) {
        return existingHal;
    }

    existingHal->removeInstance(interface, instanceOrPattern, isRegex);
    MatrixHal copy = *existingHal;
    copy.clearInstances();
    copy.insertInstance(interface, instanceOrPattern, isRegex);

    return addInternal(std::move(copy));
}

// Add all package@other_version::interface/instance as an optional instance.
// If package@this_version::interface/instance is in this (that is, some instance
// with the same package and interface and instance exists), then other_version is
// considered a possible replacement to this_version.
// See LibVintfTest.AddOptionalHal* tests for details.
bool CompatibilityMatrix::addAllHalsAsOptional(CompatibilityMatrix* other, std::string* error) {
    if (other == nullptr || other->level() <= level()) {
        return true;
    }

    for (auto& pair : other->mHals) {
        const std::string& name = pair.first;
        MatrixHal& halToAdd = pair.second;

        std::set<std::pair<std::string, std::string>> insertedInstances;
        std::set<std::pair<std::string, std::string>> insertedRegex;
        auto existingHals = getHals(name);

        halToAdd.forEachInstance([&](const std::vector<VersionRange>& versionRanges,
                                     const std::string& interface,
                                     const std::string& instanceOrPattern, bool isRegex) {
            for (auto* existingHal : existingHals) {
                // Ignore HALs with different format.
                if (halToAdd.format != existingHal->format) {
                    continue;
                }

                MatrixHal* splitInstance =
                    this->splitInstance(existingHal, interface, instanceOrPattern, isRegex);
                if (splitInstance != nullptr) {
                    splitInstance->insertVersionRanges(versionRanges);
                    if (isRegex) {
                        insertedRegex.insert(std::make_pair(interface, instanceOrPattern));
                    } else {
                        insertedInstances.insert(std::make_pair(interface, instanceOrPattern));
                    }
                }
            }
            return true;
        });

        // Add the remaining instances.
        for (const auto& pair : insertedInstances) {
            halToAdd.removeInstance(pair.first, pair.second, false /* isRegex */);
        }
        for (const auto& pair : insertedRegex) {
            halToAdd.removeInstance(pair.first, pair.second, true /* isRegex */);
        }

        if (halToAdd.instancesCount() > 0) {
            halToAdd.setOptional(true);
            if (!add(std::move(halToAdd))) {
                if (error) {
                    *error = "Cannot add HAL " + name + " for unknown reason.";
                }
                return false;
            }
        }
    }
    return true;
}

bool CompatibilityMatrix::addAllXmlFilesAsOptional(CompatibilityMatrix* other, std::string* error) {
    if (other == nullptr || other->level() <= level()) {
        return true;
    }
    for (auto& pair : other->mXmlFiles) {
        const std::string& name = pair.first;
        MatrixXmlFile& xmlFileToAdd = pair.second;

        xmlFileToAdd.mOptional = true;
        if (!addXmlFile(std::move(xmlFileToAdd))) {
            if (error) {
                *error = "Cannot add XML File " + name + " for unknown reason.";
            }
            return false;
        }
    }
    return true;
}

// Merge Kernel. See KernelInfo::getMatchedKernelRequirements for details on compatibility checks.
bool CompatibilityMatrix::addAllKernels(CompatibilityMatrix* other, std::string* error) {
    for (MatrixKernel& kernel : other->framework.mKernels) {
        if (kernel.getSourceMatrixLevel() == Level::UNSPECIFIED) {
            kernel.setSourceMatrixLevel(other->level());
        }
        KernelVersion ver = kernel.minLts();
        if (!addKernel(std::move(kernel), error)) {
            if (error) {
                *error = "Cannot add kernel version " + to_string(ver) + ": " + *error;
            }
            return false;
        }
    }
    return true;
}

bool CompatibilityMatrix::addSepolicy(CompatibilityMatrix* other, std::string* error) {
    bool success = mergeField(&this->framework.mSepolicy, &other->framework.mSepolicy);
    if (!success && error) *error = "<sepolicy> is already defined";
    return success;
}

bool CompatibilityMatrix::addAvbMetaVersion(CompatibilityMatrix* other, std::string* error) {
    bool success = mergeField(&this->framework.mAvbMetaVersion, &other->framework.mAvbMetaVersion);
    if (!success && error) *error = "<avb><vbmeta-version> is already defined";
    return success;
}

bool CompatibilityMatrix::addVndk(CompatibilityMatrix* other, std::string* error) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    bool success = mergeField(&this->device.mVndk, &other->device.mVndk);
#pragma clang diagnostic pop
    if (!success && error) *error = "<vndk> is already defined";
    return success;
}

bool CompatibilityMatrix::addVendorNdk(CompatibilityMatrix* other, std::string* error) {
    bool success = mergeField(&this->device.mVendorNdk, &other->device.mVendorNdk);
    if (!success && error) *error = "<vendor-ndk> is already defined";
    return success;
}

bool CompatibilityMatrix::addSystemSdk(CompatibilityMatrix* other, std::string* /* error */) {
    this->device.mSystemSdk.addAll(&other->device.mSystemSdk);
    return true;
}

bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt) {
    // ignore fileName().
    return lft.mType == rgt.mType && lft.mLevel == rgt.mLevel && lft.mHals == rgt.mHals &&
           lft.mXmlFiles == rgt.mXmlFiles &&
           (lft.mType != SchemaType::DEVICE ||
            (
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
                lft.device.mVndk == rgt.device.mVndk &&
#pragma clang diagnostic pop
                lft.device.mVendorNdk == rgt.device.mVendorNdk &&
                lft.device.mSystemSdk == rgt.device.mSystemSdk)) &&
           (lft.mType != SchemaType::FRAMEWORK ||
            (lft.framework.mKernels == rgt.framework.mKernels &&
             lft.framework.mSepolicy == rgt.framework.mSepolicy &&
             lft.framework.mAvbMetaVersion == rgt.framework.mAvbMetaVersion));
}

std::unique_ptr<CompatibilityMatrix> CompatibilityMatrix::combine(
    Level deviceLevel, Level kernelLevel, std::vector<CompatibilityMatrix>* matrices,
    std::string* error) {
    // Check type.
    for (const auto& e : *matrices) {
        if (e.type() != SchemaType::FRAMEWORK) {
            if (error) {
                *error = "File \"" + e.fileName() + "\" is not a framework compatibility matrix.";
                return nullptr;
            }
        }
    }

    // Matrices with unspecified (empty) level are auto-filled with deviceLevel.
    for (auto& e : *matrices) {
        if (e.level() == Level::UNSPECIFIED) {
            e.mLevel = deviceLevel;
        }
    }

    // Add from low to high FCM version so that optional <kernel> requirements are added correctly.
    // See comment in addAllAsOptional.
    std::sort(matrices->begin(), matrices->end(),
              [](const auto& x, const auto& y) { return x.level() < y.level(); });

    auto baseMatrix = std::make_unique<CompatibilityMatrix>();
    baseMatrix->mLevel = deviceLevel;
    baseMatrix->mType = SchemaType::FRAMEWORK;

    std::vector<std::string> parsedFiles;
    for (auto& e : *matrices) {
        bool success = false;
        if (e.level() < deviceLevel) {
            if (kernelLevel == Level::UNSPECIFIED) continue;
            if (e.level() < kernelLevel) continue;
            success = baseMatrix->addAllKernels(&e, error);
        } else if (e.level() == deviceLevel) {
            success = baseMatrix->addAll(&e, error);
        } else {
            success = baseMatrix->addAllAsOptional(&e, error);
        }
        if (!success) {
            if (error) {
                *error = "Conflict when merging \"" + e.fileName() + "\": " + *error + "\n" +
                         "Previous files:\n" + base::Join(parsedFiles, "\n");
            }
            return nullptr;
        }
        parsedFiles.push_back(e.fileName());
    }

    return baseMatrix;
}

std::unique_ptr<CompatibilityMatrix> CompatibilityMatrix::combineDeviceMatrices(
    std::vector<CompatibilityMatrix>* matrices, std::string* error) {
    auto baseMatrix = std::make_unique<CompatibilityMatrix>();
    baseMatrix->mType = SchemaType::DEVICE;

    std::vector<std::string> parsedFiles;
    for (auto& e : *matrices) {
        bool success = baseMatrix->addAll(&e, error);
        if (!success) {
            if (error) {
                *error = "Conflict when merging \"" + e.fileName() + "\": " + *error + "\n" +
                         "Previous files:\n" + base::Join(parsedFiles, "\n");
            }
            return nullptr;
        }
        parsedFiles.push_back(e.fileName());
    }
    return baseMatrix;
}

bool CompatibilityMatrix::addAll(CompatibilityMatrix* inputMatrix, std::string* error) {
    if (!addAllHals(inputMatrix, error) || !addAllXmlFiles(inputMatrix, error) ||
        !addAllKernels(inputMatrix, error) || !addSepolicy(inputMatrix, error) ||
        !addAvbMetaVersion(inputMatrix, error) || !addVndk(inputMatrix, error) ||
        !addVendorNdk(inputMatrix, error) || !addSystemSdk(inputMatrix, error)) {
        if (error) {
            *error = "File \"" + inputMatrix->fileName() + "\" cannot be added: " + *error + ".";
        }
        return false;
    }
    return true;
}

bool CompatibilityMatrix::addAllAsOptional(CompatibilityMatrix* inputMatrix, std::string* error) {
    if (!addAllHalsAsOptional(inputMatrix, error) ||
        !addAllXmlFilesAsOptional(inputMatrix, error) || !addAllKernels(inputMatrix, error)) {
        if (error) {
            *error = "File \"" + inputMatrix->fileName() + "\" cannot be added: " + *error;
        }
        return false;
    }
    // ignore <sepolicy> requirement from higher level
    // ignore <avb> requirement from higher level
    return true;
}

bool CompatibilityMatrix::forEachInstanceOfVersion(
    HalFormat format, const std::string& package, const Version& expectVersion,
    const std::function<bool(const MatrixInstance&)>& func) const {
    for (const MatrixHal* hal : getHals(package)) {
        bool cont = hal->forEachInstance([&](const MatrixInstance& matrixInstance) {
            if (matrixInstance.format() == format &&
                matrixInstance.versionRange().contains(expectVersion)) {
                return func(matrixInstance);
            }
            return true;
        });
        if (!cont) return false;
    }
    return true;
}

bool CompatibilityMatrix::matchInstance(HalFormat format, const std::string& halName,
                                        const Version& version, const std::string& interfaceName,
                                        const std::string& instance) const {
    bool found = false;
    (void)forEachInstanceOfInterface(format, halName, version, interfaceName,
                                     [&found, &instance](const auto& e) {
                                         found |= (e.matchInstance(instance));
                                         return !found;  // if not found, continue
                                     });
    return found;
}

std::vector<VersionRange> CompatibilityMatrix::getSepolicyVersions() const {
    if (type() == SchemaType::FRAMEWORK) return framework.mSepolicy.sepolicyVersions();
    return {};
}

std::string CompatibilityMatrix::getVendorNdkVersion() const {
    return type() == SchemaType::DEVICE ? device.mVendorNdk.version() : "";
}

Level CompatibilityMatrix::getSourceMatrixLevel(const MatrixKernel* matrixKernel) const {
    CHECK(std::find_if(framework.mKernels.begin(), framework.mKernels.end(),
                       [matrixKernel](const auto& e) { return &e == matrixKernel; }) !=
          framework.mKernels.end());
    Level ret = matrixKernel->getSourceMatrixLevel();
    if (ret != Level::UNSPECIFIED) return ret;
    return level();
}

} // namespace vintf
} // namespace android
