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


#ifndef ANDROID_VINTF_HAL_MANIFEST_H
#define ANDROID_VINTF_HAL_MANIFEST_H

#include <utils/Errors.h>
#include <map>
#include <string>
#include <vector>

#include "FileSystem.h"
#include "HalGroup.h"
#include "Level.h"
#include "ManifestHal.h"
#include "ManifestInstance.h"
#include "MapValueIterator.h"
#include "SchemaType.h"
#include "SystemSdk.h"
#include "VendorNdk.h"
#include "Version.h"
#include "Vndk.h"
#include "XmlFileGroup.h"

namespace android {
namespace vintf {

struct MatrixHal;
struct CompatibilityMatrix;

namespace details {
using InstancesOfVersion =
    std::map<std::string /* interface */, std::set<std::string /* instance */>>;
using Instances = std::map<Version, InstancesOfVersion>;
}  // namespace details

// A HalManifest is reported by the hardware and query-able from
// framework code. This is the API for the framework.
struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> {
   public:

    // Construct a device HAL manifest.
    HalManifest() : mType(SchemaType::DEVICE) {}

    bool add(ManifestHal&& hal) override;

    // Given a component name (e.g. "android.hardware.camera"),
    // return getHal(name)->transport if the component exist and v exactly matches
    // one of the versions in that component, else EMPTY
    Transport getTransport(const std::string &name, const Version &v,
            const std::string &interfaceName, const std::string &instanceName) const;

    // Check compatibility against a compatibility matrix. Considered compatible if
    // - framework manifest vs. device compat-mat
    //     - checkIncompatibility for HALs returns only optional HALs
    //     - one of manifest.vndk match compat-mat.vndk
    // - device manifest vs. framework compat-mat
    //     - checkIncompatibility for HALs returns only optional HALs
    //     - manifest.sepolicy.version match one of compat-mat.sepolicy.sepolicy-version
    bool checkCompatibility(const CompatibilityMatrix &mat, std::string *error = nullptr) const;

    // Generate a compatibility matrix such that checkCompatibility will return true.
    CompatibilityMatrix generateCompatibleMatrix() const;

    // Returns all component names.
    std::set<std::string> getHalNames() const;

    // Returns all component names and versions, e.g.
    // "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2",
    // "android.hardware.nfc@1.0"]
    std::set<std::string> getHalNamesAndVersions() const;

    // Type of the manifest. FRAMEWORK or DEVICE.
    SchemaType type() const;
    void setType(SchemaType type);

    // FCM version that it implements.
    Level level() const;

    // device.mSepolicyVersion. Assume type == device.
    // Abort if type != device.
    const Version &sepolicyVersion() const;

    // framework.mVendorNdks. Assume type == framework.
    // Abort if type != framework.
    const std::vector<VendorNdk>& vendorNdks() const;

    // If the corresponding <xmlfile> with the given version exists,
    // - Return the overridden <path> if it is present,
    // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml
    // Otherwise if the <xmlfile> entry does not exist, "" is returned.
    std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const;

    // Get metaversion of this manifest.
    Version getMetaVersion() const;

    bool forEachInstanceOfVersion(
        const std::string& package, const Version& expectVersion,
        const std::function<bool(const ManifestInstance&)>& func) const override;

    // Alternative to forEachInstance if you just need a set of instance names instead.
    std::set<std::string> getInstances(const std::string& halName, const Version& version,
                                       const std::string& interfaceName) const;

    // Return whether instance is in getInstances(...).
    bool hasInstance(const std::string& halName, const Version& version,
                     const std::string& interfaceName, const std::string& instance) const;

    // Insert the given instance. After inserting it, the instance will be available via
    // forEachInstance* functions. This modifies the manifest.
    // Return whether this operation is successful.
    bool insertInstance(const FqInstance& fqInstance, Transport transport, Arch arch, HalFormat fmt,
                        std::string* error = nullptr);

   protected:
    // Check before add()
    bool shouldAdd(const ManifestHal& toAdd) const override;
    bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override;

   private:
    friend struct HalManifestConverter;
    friend class VintfObject;
    friend class AssembleVintfImpl;
    friend struct LibVintfTest;
    friend std::string dump(const HalManifest &vm);
    friend bool operator==(const HalManifest &lft, const HalManifest &rgt);

    status_t fetchAllInformation(const FileSystem* fileSystem, const std::string& path,
                                 std::string* error = nullptr);

    details::Instances expandInstances(const std::string& name) const;
    // Check if all instances in matrixHal is supported in this manifest.
    bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const;

    // Return a list of error messages (for each <hal> name) that does NOT conform to
    // the given compatibility matrix. It does not contain components that are optional.
    // That is, return empty list iff
    // (instance in matrix) => (instance in manifest).
    std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const;

    void removeHals(const std::string& name, size_t majorVer);

    // Returns a list of instance names that are in this manifest but
    // are not specified in the given matrix, whether the HAL is specified as an optional or
    // required HAL.
    // That is, return empty list iff
    // (instance in manifest) => (instance in matrix).
    std::set<std::string> checkUnusedHals(const CompatibilityMatrix& mat) const;

    // Check that manifest has no entries.
    bool empty() const;

    SchemaType mType;
    Level mLevel = Level::UNSPECIFIED;
    // version attribute. Default is 1.0 for manifests created programatically.
    Version mMetaVersion{1, 0};

    // entries for device hal manifest only
    struct {
        Version mSepolicyVersion;
    } device;

    // entries for framework hal manifest only
    struct {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        std::vector<Vndk> mVndks;
#pragma clang diagnostic pop

        std::vector<VendorNdk> mVendorNdks;
        SystemSdk mSystemSdk;
    } framework;
};


} // namespace vintf
} // namespace android

#endif // ANDROID_VINTF_HAL_MANIFEST_H
