//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// feature_support_util.cpp: Helps client APIs make decisions based on rules
// data files.  For example, the Android EGL loader uses this library to
// determine whether to use ANGLE or a native GLES driver.

#include "feature_support_util.h"
#include <json/json.h>
#include <string.h>
#include "common/platform.h"
#if defined(ANGLE_PLATFORM_ANDROID)
#    include <android/log.h>
#    include <unistd.h>
#endif
#include <fstream>
#include <list>
#include "../gpu_info_util/SystemInfo.h"

namespace angle
{

#if defined(ANGLE_PLATFORM_ANDROID)
// Define ANGLE_FEATURE_UTIL_LOG_VERBOSE if you want VERBOSE to output
// ANGLE_FEATURE_UTIL_LOG_VERBOSE is automatically defined when is_debug = true

#    define ERR(...) __android_log_print(ANDROID_LOG_ERROR, "ANGLE", __VA_ARGS__)
#    define WARN(...) __android_log_print(ANDROID_LOG_WARN, "ANGLE", __VA_ARGS__)
#    define INFO(...) __android_log_print(ANDROID_LOG_INFO, "ANGLE", __VA_ARGS__)
#    define DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG, "ANGLE", __VA_ARGS__)
#    ifdef ANGLE_FEATURE_UTIL_LOG_VERBOSE
#        define VERBOSE(...) __android_log_print(ANDROID_LOG_VERBOSE, "ANGLE", __VA_ARGS__)
#    else
#        define VERBOSE(...) ((void)0)
#    endif
#else  // defined(ANDROID)
#    define ERR(...) printf(__VA_ARGS__)
#    define WARN(...) printf(__VA_ARGS__)
#    define INFO(...) printf(__VA_ARGS__)
#    define DEBUG(...) printf(__VA_ARGS__)
#    define VERBOSE(...) printf(__VA_ARGS__)
#endif  // defined(ANDROID)

// JSON values are generally composed of either:
//  - Objects, which are a set of comma-separated string:value pairs (note the recursive nature)
//  - Arrays, which are a set of comma-separated values.
// We'll call the string in a string:value pair the "identifier".  These identifiers are defined
// below, as follows:

// The JSON identifier for the top-level set of rules.  This is an object, the value of which is an
// array of rules.  The rules will be processed in order.  If a rule matches, the rule's version of
// the answer (true or false) becomes the new answer.  After all rules are processed, the
// most-recent answer is the final answer.
constexpr char kJsonRules[] = "Rules";
// The JSON identifier for a given rule.  A rule is an object, the first string:value pair is this
// identifier (i.e. "Rule") as the string and the value is a user-firendly description of the rule:
constexpr char kJsonRule[] = "Rule";
// Within a rule, the JSON identifier for the answer--whether or not to use ANGLE.  The value is a
// boolean (i.e. true or false).
constexpr char kJsonUseANGLE[] = "UseANGLE";

// Within a rule, the JSON identifier for describing one or more applications.  The value is an
// array of objects, each object of which can specify attributes of an application.
constexpr char kJsonApplications[] = "Applications";
// Within an object that describes the attributes of an application, the JSON identifier for the
// name of the application (e.g. "com.google.maps").  The value is a string.  If any other
// attributes will be specified, this must be the first attribute specified in the object.
constexpr char kJsonAppName[] = "AppName";

// Within a rule, the JSON identifier for describing one or more devices.  The value is an
// array of objects, each object of which can specify attributes of a device.
constexpr char kJsonDevices[] = "Devices";
// Within an object that describes the attributes of a device, the JSON identifier for the
// manufacturer of the device.  The value is a string.  If any other non-GPU attributes will be
// specified, this must be the first attribute specified in the object.
constexpr char kJsonManufacturer[] = "Manufacturer";
// Within an object that describes the attributes of a device, the JSON identifier for the
// model of the device.  The value is a string.
constexpr char kJsonModel[] = "Model";

// Within an object that describes the attributes of a device, the JSON identifier for describing
// one or more GPUs/drivers used in the device.  The value is an
// array of objects, each object of which can specify attributes of a GPU and its driver.
constexpr char kJsonGPUs[] = "GPUs";
// Within an object that describes the attributes of a GPU and driver, the JSON identifier for the
// vendor of the device/driver.  The value is a string.  If any other attributes will be specified,
// this must be the first attribute specified in the object.
constexpr char kJsonVendor[] = "Vendor";
// Within an object that describes the attributes of a GPU and driver, the JSON identifier for the
// deviceId of the device.  The value is an unsigned integer.  If the driver version will be
// specified, this must preceded the version attributes specified in the object.
constexpr char kJsonDeviceId[] = "DeviceId";

// Within an object that describes the attributes of either an application or a GPU, the JSON
// identifier for the major version of that application or GPU driver.  The value is a positive
// integer number.  Not specifying a major version implies a wildcard for all values of a version.
constexpr char kJsonVerMajor[] = "VerMajor";
// Within an object that describes the attributes of either an application or a GPU, the JSON
// identifier for the minor version of that application or GPU driver.  The value is a positive
// integer number.  In order to specify a minor version, it must be specified immediately after the
// major number associated with it.  Not specifying a minor version implies a wildcard for the
// minor, subminor, and patch values of a version.
constexpr char kJsonVerMinor[] = "VerMinor";
// Within an object that describes the attributes of either an application or a GPU, the JSON
// identifier for the subminor version of that application or GPU driver.  The value is a positive
// integer number.  In order to specify a subminor version, it must be specified immediately after
// the minor number associated with it.  Not specifying a subminor version implies a wildcard for
// the subminor and patch values of a version.
constexpr char kJsonVerSubMinor[] = "VerSubMinor";
// Within an object that describes the attributes of either an application or a GPU, the JSON
// identifier for the patch version of that application or GPU driver.  The value is a positive
// integer number.  In order to specify a patch version, it must be specified immediately after the
// subminor number associated with it.  Not specifying a patch version implies a wildcard for the
// patch value of a version.
constexpr char kJsonVerPatch[] = "VerPatch";

// This encapsulates a std::string.  The default constructor (not given a string) assumes that this
// is a wildcard (i.e. will match all other StringPart objects).
class StringPart
{
  public:
    StringPart() : mPart(""), mWildcard(true) {}
    StringPart(const std::string part) : mPart(part), mWildcard(false) {}
    ~StringPart() {}
    bool match(const StringPart &toCheck) const
    {
        return (mWildcard || toCheck.mWildcard || (toCheck.mPart == mPart));
    }

  public:
    std::string mPart;
    bool mWildcard;
};

// This encapsulates a 32-bit unsigned integer.  The default constructor (not given a number)
// assumes that this is a wildcard (i.e. will match all other IntegerPart objects).
class IntegerPart
{
  public:
    IntegerPart() : mPart(0), mWildcard(true) {}
    IntegerPart(uint32_t part) : mPart(part), mWildcard(false) {}
    ~IntegerPart() {}
    bool match(const IntegerPart &toCheck) const
    {
        return (mWildcard || toCheck.mWildcard || (toCheck.mPart == mPart));
    }

  public:
    uint32_t mPart;
    bool mWildcard;
};

// This encapsulates a list of other classes, each of which will have a match() and logItem()
// method.  The common constructor (given a type, but not any list items) assumes that this is
// a wildcard (i.e. will match all other ListOf<t> objects).
template <class T>
class ListOf
{
  public:
    ListOf(const std::string listType) : mWildcard(true), mListType(listType) {}
    ~ListOf() { mList.clear(); }
    void addItem(const T &toAdd)
    {
        mList.push_back(toAdd);
        mWildcard = false;
    }
    bool match(const T &toCheck) const
    {
        VERBOSE("\t\t Within ListOf<%s> match: wildcards are %s and %s,\n", mListType.c_str(),
                mWildcard ? "true" : "false", toCheck.mWildcard ? "true" : "false");
        if (mWildcard || toCheck.mWildcard)
        {
            return true;
        }
        for (const T &it : mList)
        {
            VERBOSE("\t\t   Within ListOf<%s> match: calling match on sub-item is %s,\n",
                    mListType.c_str(), it.match(toCheck) ? "true" : "false");
            if (it.match(toCheck))
            {
                return true;
            }
        }
        return false;
    }
    bool match(const ListOf<T> &toCheck) const
    {
        VERBOSE("\t\t Within ListOf<%s> match: wildcards are %s and %s,\n", mListType.c_str(),
                mWildcard ? "true" : "false", toCheck.mWildcard ? "true" : "false");
        if (mWildcard || toCheck.mWildcard)
        {
            return true;
        }
        // If we make it to here, both this and toCheck have at least one item in their mList
        for (const T &it : toCheck.mList)
        {
            if (match(it))
            {
                return true;
            }
        }
        return false;
    }
    void logListOf(const std::string prefix, const std::string name) const
    {
        if (mWildcard)
        {
            VERBOSE("%sListOf%s is wildcarded to always match", prefix.c_str(), name.c_str());
        }
        else
        {
            VERBOSE("%sListOf%s has %d item(s):", prefix.c_str(), name.c_str(),
                    static_cast<int>(mList.size()));
            for (auto &it : mList)
            {
                it.logItem();
            }
        }
    }

    bool mWildcard;

  private:
    std::string mListType;
    std::vector<T> mList;
};

// This encapsulates up-to four 32-bit unsigned integers, that represent a potentially-complex
// version number.  The default constructor (not given any numbers) assumes that this is a wildcard
// (i.e. will match all other Version objects).  Each part of a Version is stored in an IntegerPart
// class, and so may be wildcarded as well.
class Version
{
  public:
    Version(uint32_t major, uint32_t minor, uint32_t subminor, uint32_t patch)
        : mMajor(major), mMinor(minor), mSubminor(subminor), mPatch(patch), mWildcard(false)
    {}
    Version(uint32_t major, uint32_t minor, uint32_t subminor)
        : mMajor(major), mMinor(minor), mSubminor(subminor), mWildcard(false)
    {}
    Version(uint32_t major, uint32_t minor) : mMajor(major), mMinor(minor), mWildcard(false) {}
    Version(uint32_t major) : mMajor(major), mWildcard(false) {}
    Version() : mWildcard(true) {}
    Version(const Version &toCopy)
        : mMajor(toCopy.mMajor),
          mMinor(toCopy.mMinor),
          mSubminor(toCopy.mSubminor),
          mPatch(toCopy.mPatch),
          mWildcard(toCopy.mWildcard)
    {}
    ~Version() {}

    static Version *CreateVersionFromJson(const Json::Value &jObject)
    {
        Version *version = nullptr;
        // A major version must be provided before a minor, and so on:
        if (jObject.isMember(kJsonVerMajor) && jObject[kJsonVerMajor].isInt())
        {
            int major = jObject[kJsonVerMajor].asInt();
            if (jObject.isMember(kJsonVerMinor) && jObject[kJsonVerMinor].isInt())
            {
                int minor = jObject[kJsonVerMinor].asInt();
                if (jObject.isMember(kJsonVerSubMinor) && jObject[kJsonVerSubMinor].isInt())
                {
                    int subMinor = jObject[kJsonVerSubMinor].asInt();
                    if (jObject.isMember(kJsonVerPatch) && jObject[kJsonVerPatch].isInt())
                    {
                        int patch = jObject[kJsonVerPatch].asInt();
                        version   = new Version(major, minor, subMinor, patch);
                    }
                    else
                    {
                        version = new Version(major, minor, subMinor);
                    }
                }
                else
                {
                    version = new Version(major, minor);
                }
            }
            else
            {
                version = new Version(major);
            }
        }
        return version;
    }

    bool match(const Version &toCheck) const
    {
        VERBOSE("\t\t\t Within Version %d,%d,%d,%d match(%d,%d,%d,%d): wildcards are %s and %s,\n",
                mMajor.mPart, mMinor.mPart, mSubminor.mPart, mPatch.mPart, toCheck.mMajor.mPart,
                toCheck.mMinor.mPart, toCheck.mSubminor.mPart, toCheck.mPatch.mPart,
                mWildcard ? "true" : "false", toCheck.mWildcard ? "true" : "false");
        if (!(mWildcard || toCheck.mWildcard))
        {
            VERBOSE("\t\t\t   mMajor match is %s, mMinor is %s, mSubminor is %s, mPatch is %s\n",
                    mMajor.match(toCheck.mMajor) ? "true" : "false",
                    mMinor.match(toCheck.mMinor) ? "true" : "false",
                    mSubminor.match(toCheck.mSubminor) ? "true" : "false",
                    mPatch.match(toCheck.mPatch) ? "true" : "false");
        }
        return (mWildcard || toCheck.mWildcard ||
                (mMajor.match(toCheck.mMajor) && mMinor.match(toCheck.mMinor) &&
                 mSubminor.match(toCheck.mSubminor) && mPatch.match(toCheck.mPatch)));
    }
    std::string getString() const
    {
        if (mWildcard)
        {
            return "*";
        }
        else
        {
            char ret[100];
            // Must at least have a major version:
            if (!mMinor.mWildcard)
            {
                if (!mSubminor.mWildcard)
                {
                    if (!mPatch.mWildcard)
                    {
                        snprintf(ret, 100, "%d.%d.%d.%d", mMajor.mPart, mMinor.mPart,
                                 mSubminor.mPart, mPatch.mPart);
                    }
                    else
                    {
                        snprintf(ret, 100, "%d.%d.%d.*", mMajor.mPart, mMinor.mPart,
                                 mSubminor.mPart);
                    }
                }
                else
                {
                    snprintf(ret, 100, "%d.%d.*", mMajor.mPart, mMinor.mPart);
                }
            }
            else
            {
                snprintf(ret, 100, "%d.*", mMajor.mPart);
            }
            std::string retString = ret;
            return retString;
        }
    }

  public:
    IntegerPart mMajor;
    IntegerPart mMinor;
    IntegerPart mSubminor;
    IntegerPart mPatch;
    bool mWildcard;
};

// This encapsulates an application, and potentially the application's Version.  The default
// constructor (not given any values) assumes that this is a wildcard (i.e. will match all
// other Application objects).  Each part of an Application is stored in a class that may
// also be wildcarded.
class Application
{
  public:
    Application(const std::string name, const Version &version)
        : mName(name), mVersion(version), mWildcard(false)
    {}
    Application(const std::string name) : mName(name), mVersion(), mWildcard(false) {}
    Application() : mName(), mVersion(), mWildcard(true) {}
    ~Application() {}

    static Application *CreateApplicationFromJson(const Json::Value &jObject)
    {
        Application *application = nullptr;

        // If an application is listed, the application's name is required:
        std::string appName = jObject[kJsonAppName].asString();

        // The application's version is optional:
        Version *version = Version::CreateVersionFromJson(jObject);
        if (version)
        {
            application = new Application(appName, *version);
            delete version;
        }
        else
        {
            application = new Application(appName);
        }
        return application;
    }

    bool match(const Application &toCheck) const
    {
        return (mWildcard || toCheck.mWildcard ||
                (toCheck.mName.match(mName) && toCheck.mVersion.match(mVersion)));
    }
    void logItem() const
    {
        if (mWildcard)
        {
            VERBOSE("      Wildcard (i.e. will match all applications)");
        }
        else if (!mVersion.mWildcard)
        {
            VERBOSE("      Application \"%s\" (version: %s)", mName.mPart.c_str(),
                    mVersion.getString().c_str());
        }
        else
        {
            VERBOSE("      Application \"%s\"", mName.mPart.c_str());
        }
    }

  public:
    StringPart mName;
    Version mVersion;
    bool mWildcard;
};

// This encapsulates a GPU and its driver.  The default constructor (not given any values) assumes
// that this is a wildcard (i.e. will match all other GPU objects).  Each part of a GPU is stored
// in a class that may also be wildcarded.
class GPU
{
  public:
    GPU(const std::string vendor, uint32_t deviceId, const Version &version)
        : mVendor(vendor), mDeviceId(IntegerPart(deviceId)), mVersion(version), mWildcard(false)
    {}
    GPU(const std::string vendor, uint32_t deviceId)
        : mVendor(vendor), mDeviceId(IntegerPart(deviceId)), mVersion(), mWildcard(false)
    {}
    GPU(const std::string vendor) : mVendor(vendor), mDeviceId(), mVersion(), mWildcard(false) {}
    GPU() : mVendor(), mDeviceId(), mVersion(), mWildcard(true) {}
    bool match(const GPU &toCheck) const
    {
        VERBOSE("\t\t Within GPU match: wildcards are %s and %s,\n", mWildcard ? "true" : "false",
                toCheck.mWildcard ? "true" : "false");
        VERBOSE("\t\t   mVendor = \"%s\" and toCheck.mVendor = \"%s\"\n", mVendor.mPart.c_str(),
                toCheck.mVendor.mPart.c_str());
        VERBOSE("\t\t   mDeviceId = %d and toCheck.mDeviceId = %d\n", mDeviceId.mPart,
                toCheck.mDeviceId.mPart);
        VERBOSE("\t\t   mVendor match is %s, mDeviceId is %s, mVersion is %s\n",
                toCheck.mVendor.match(mVendor) ? "true" : "false",
                toCheck.mDeviceId.match(mDeviceId) ? "true" : "false",
                toCheck.mVersion.match(mVersion) ? "true" : "false");
        return (mWildcard || toCheck.mWildcard ||
                (toCheck.mVendor.match(mVendor) && toCheck.mDeviceId.match(mDeviceId) &&
                 toCheck.mVersion.match(mVersion)));
    }
    ~GPU() {}

    static GPU *CreateGpuFromJson(const Json::Value &jObject)
    {
        GPU *gpu = nullptr;

        // If a GPU is listed, the vendor name is required:
        if (jObject.isMember(kJsonVendor) && jObject[kJsonVendor].isString())
        {
            std::string vendor = jObject[kJsonVendor].asString();
            // If a version is given, the deviceId is required:
            if (jObject.isMember(kJsonDeviceId) && jObject[kJsonDeviceId].isUInt())
            {
                uint32_t deviceId = jObject[kJsonDeviceId].asUInt();
                Version *version  = Version::CreateVersionFromJson(jObject);
                if (version)
                {
                    gpu = new GPU(vendor, deviceId, *version);
                    delete version;
                }
                else
                {
                    gpu = new GPU(vendor, deviceId);
                }
            }
            else
            {
                gpu = new GPU(vendor);
            }
        }
        else
        {
            WARN("Asked to parse a GPU, but no vendor found");
        }

        return gpu;
    }

    void logItem() const
    {
        if (mWildcard)
        {
            VERBOSE("          Wildcard (i.e. will match all GPUs)");
        }
        else
        {
            if (!mDeviceId.mWildcard)
            {
                if (!mVersion.mWildcard)
                {
                    VERBOSE("\t     GPU vendor: %s, deviceId: 0x%x, version: %s",
                            mVendor.mPart.c_str(), mDeviceId.mPart, mVersion.getString().c_str());
                }
                else
                {
                    VERBOSE("\t     GPU vendor: %s, deviceId: 0x%x", mVendor.mPart.c_str(),
                            mDeviceId.mPart);
                }
            }
            else
            {
                VERBOSE("\t     GPU vendor: %s", mVendor.mPart.c_str());
            }
        }
    }

  public:
    StringPart mVendor;
    IntegerPart mDeviceId;
    Version mVersion;
    bool mWildcard;
};

// This encapsulates a device, and potentially the device's model and/or a list of GPUs/drivers
// associated with the Device.  The default constructor (not given any values) assumes that this is
// a wildcard (i.e. will match all other Device objects).  Each part of a Device is stored in a
// class that may also be wildcarded.
class Device
{
  public:
    Device(const std::string manufacturer, const std::string model)
        : mManufacturer(manufacturer), mModel(model), mGpuList("GPU"), mWildcard(false)
    {}
    Device(const std::string manufacturer)
        : mManufacturer(manufacturer), mModel(), mGpuList("GPU"), mWildcard(false)
    {}
    Device() : mManufacturer(), mModel(), mGpuList("GPU"), mWildcard(true) {}
    ~Device() {}

    static Device *CreateDeviceFromJson(const Json::Value &jObject)
    {
        Device *device = nullptr;
        if (jObject.isMember(kJsonManufacturer) && jObject[kJsonManufacturer].isString())
        {
            std::string manufacturerName = jObject[kJsonManufacturer].asString();
            // We don't let a model be specified without also specifying an Manufacturer:
            if (jObject.isMember(kJsonModel) && jObject[kJsonModel].isString())
            {
                std::string model = jObject[kJsonModel].asString();
                device            = new Device(manufacturerName, model);
            }
            else
            {
                device = new Device(manufacturerName);
            }
        }
        else
        {
            // This case is not treated as an error because a rule may wish to only call out one or
            // more GPUs, but not any specific Manufacturer (e.g. for any manufacturer's device
            // that uses a GPU from Vendor-A, with DeviceID-Foo, and with driver version 1.2.3.4):
            device = new Device();
        }
        return device;
    }

    void addGPU(const GPU &gpu) { mGpuList.addItem(gpu); }
    bool match(const Device &toCheck) const
    {
        VERBOSE("\t Within Device match: wildcards are %s and %s,\n", mWildcard ? "true" : "false",
                toCheck.mWildcard ? "true" : "false");
        if (!(mWildcard || toCheck.mWildcard))
        {
            VERBOSE("\t   Manufacturer match is %s, model is %s\n",
                    toCheck.mManufacturer.match(mManufacturer) ? "true" : "false",
                    toCheck.mModel.match(mModel) ? "true" : "false");
        }
        VERBOSE("\t   Need to check ListOf<GPU>\n");
        return ((mWildcard || toCheck.mWildcard ||
                 // The wildcards can override the Manufacturer/Model check, but not the GPU check
                 (toCheck.mManufacturer.match(mManufacturer) && toCheck.mModel.match(mModel))) &&
                mGpuList.match(toCheck.mGpuList));
    }
    void logItem() const
    {
        if (mWildcard)
        {
            if (mGpuList.mWildcard)
            {
                VERBOSE("      Wildcard (i.e. will match all devices)");
                return;
            }
            else
            {
                VERBOSE(
                    "      Device with any manufacturer and model"
                    ", and with the following GPUs:");
            }
        }
        else
        {
            if (!mModel.mWildcard)
            {
                VERBOSE(
                    "      Device manufacturer: \"%s\" and model \"%s\""
                    ", and with the following GPUs:",
                    mManufacturer.mPart.c_str(), mModel.mPart.c_str());
            }
            else
            {
                VERBOSE(
                    "      Device manufacturer: \"%s\""
                    ", and with the following GPUs:",
                    mManufacturer.mPart.c_str());
            }
        }
        mGpuList.logListOf("        ", "GPUs");
    }

  public:
    StringPart mManufacturer;
    StringPart mModel;
    ListOf<GPU> mGpuList;
    bool mWildcard;
};

// This encapsulates a particular scenario to check against the rules.  A Scenario is similar to a
// Rule, except that a Rule has an answer and potentially many wildcards, and a Scenario is the
// fully-specified combination of an Application and a Device that is proposed to be run with
// ANGLE.  It is compared with the list of Rules.
class Scenario
{
  public:
    Scenario(const char *appName, const char *deviceMfr, const char *deviceModel)
        : mApplication(Application(appName)), mDevice(Device(deviceMfr, deviceModel))
    {}
    ~Scenario() {}
    void logScenario()
    {
        VERBOSE("  Scenario to compare against the rules");
        VERBOSE("    Application:");
        mApplication.logItem();
        VERBOSE("    Device:");
        mDevice.logItem();
    }

  public:
    Application mApplication;
    Device mDevice;
};

// This encapsulates a Rule that provides an answer based on whether a particular Scenario matches
// the Rule.  A Rule always has an answer, but can potentially wildcard every item in it (i.e.
// match every scenario).
class Rule
{
  public:
    Rule(const std::string description, bool useANGLE)
        : mDescription(description),
          mAppList("Application"),
          mDevList("Device"),
          mUseANGLE(useANGLE)
    {}
    ~Rule() {}
    void addApp(const Application &app) { mAppList.addItem(app); }
    void addDevice(const Device &dev) { mDevList.addItem(dev); }
    bool match(const Scenario &toCheck) const
    {
        VERBOSE("    Within \"%s\" Rule: application match is %s and device match is %s\n",
                mDescription.c_str(), mAppList.match(toCheck.mApplication) ? "true" : "false",
                mDevList.match(toCheck.mDevice) ? "true" : "false");
        return (mAppList.match(toCheck.mApplication) && mDevList.match(toCheck.mDevice));
    }
    bool getUseANGLE() const { return mUseANGLE; }
    void logRule() const
    {
        VERBOSE("  Rule: \"%s\" %s ANGLE", mDescription.c_str(),
                mUseANGLE ? "enables" : "disables");
        mAppList.logListOf("    ", "Applications");
        mDevList.logListOf("    ", "Devices");
    }

    std::string mDescription;
    ListOf<Application> mAppList;
    ListOf<Device> mDevList;
    bool mUseANGLE;
};

// This encapsulates a list of Rules that Scenarios are matched against.  A Scenario is compared
// with each Rule, in order.  Any time a Scenario matches a Rule, the current answer is overridden
// with the answer of the matched Rule.
class RuleList
{
  public:
    RuleList() {}
    ~RuleList() { mRuleList.clear(); }

    static RuleList *ReadRulesFromJsonString(const std::string jsonFileContents)
    {
        RuleList *rules = new RuleList;

        // Open the file and start parsing it:
        Json::Reader jReader;
        Json::Value jTopLevelObject;
        jReader.parse(jsonFileContents, jTopLevelObject);
        Json::Value jRules = jTopLevelObject[kJsonRules];
        for (unsigned int ruleIndex = 0; ruleIndex < jRules.size(); ruleIndex++)
        {
            Json::Value jRule           = jRules[ruleIndex];
            std::string ruleDescription = jRule[kJsonRule].asString();
            bool useANGLE               = jRule[kJsonUseANGLE].asBool();
            Rule *newRule               = new Rule(ruleDescription, useANGLE);

            Json::Value jApps = jRule[kJsonApplications];
            for (unsigned int appIndex = 0; appIndex < jApps.size(); appIndex++)
            {
                Json::Value jApp    = jApps[appIndex];
                Application *newApp = Application::CreateApplicationFromJson(jApp);
                newRule->addApp(*newApp);
                delete newApp;
            }

            Json::Value jDevs = jRule[kJsonDevices];
            for (unsigned int deviceIndex = 0; deviceIndex < jDevs.size(); deviceIndex++)
            {
                Json::Value jDev = jDevs[deviceIndex];
                Device *newDev   = Device::CreateDeviceFromJson(jDev);

                Json::Value jGPUs = jDev[kJsonGPUs];
                for (unsigned int gpuIndex = 0; gpuIndex < jGPUs.size(); gpuIndex++)
                {
                    Json::Value jGPU = jGPUs[gpuIndex];
                    GPU *newGPU      = GPU::CreateGpuFromJson(jGPU);
                    if (newGPU)
                    {
                        newDev->addGPU(*newGPU);
                        delete newGPU;
                    }
                }
                newRule->addDevice(*newDev);
                delete newDev;
            }

            rules->addRule(*newRule);
            delete newRule;
        }

        // Make sure there is at least one, default rule.  If not, add it here:
        if (rules->mRuleList.size() == 0)
        {
            Rule defaultRule("Default Rule", false);
            rules->addRule(defaultRule);
        }
        return rules;
    }

    void addRule(const Rule &rule) { mRuleList.push_back(rule); }
    bool getUseANGLE(const Scenario &toCheck)
    {
        // Initialize useANGLE to the system-wide default (that should be set in the default
        // rule, but just in case, set it here too):
        bool useANGLE = false;
        VERBOSE("Checking scenario against %d ANGLE-for-Android rules:",
                static_cast<int>(mRuleList.size()));

        for (const Rule &rule : mRuleList)
        {
            VERBOSE("  Checking Rule: \"%s\" (to see whether there's a match)",
                    rule.mDescription.c_str());
            if (rule.match(toCheck))
            {
                VERBOSE("  -> Rule matches.  Setting useANGLE to %s",
                        rule.getUseANGLE() ? "true" : "false");
                useANGLE = rule.getUseANGLE();
            }
            else
            {
                VERBOSE("  -> Rule doesn't match.");
            }
        }

        return useANGLE;
    }
    void logRules()
    {
        VERBOSE("Showing %d ANGLE-for-Android rules:", static_cast<int>(mRuleList.size()));
        for (const Rule &rule : mRuleList)
        {
            rule.logRule();
        }
    }

  public:
    std::vector<Rule> mRuleList;
};

}  // namespace angle

extern "C" {

using namespace angle;

// This function is part of the version-2 API:
ANGLE_EXPORT bool ANGLEGetFeatureSupportUtilAPIVersion(unsigned int *versionToUse)
{
    if (!versionToUse || (*versionToUse < kFeatureVersion_LowestSupported))
    {
        // The versionToUse is either nullptr or is less than the lowest version supported, which
        // is an error.
        return false;
    }
    if (*versionToUse > kFeatureVersion_HighestSupported)
    {
        // The versionToUse is greater than the highest version supported; change it to the
        // highest version supported (caller will decide if it can use that version).
        *versionToUse = kFeatureVersion_HighestSupported;
    }
    return true;
}

// This function is part of the version-2 API:
ANGLE_EXPORT bool ANGLEAndroidParseRulesString(const char *rulesString,
                                               RulesHandle *rulesHandle,
                                               int *rulesVersion)
{
    if (!rulesString || !rulesHandle || !rulesVersion)
    {
        return false;
    }

    std::string rulesFileContents = rulesString;
    RuleList *rules               = RuleList::ReadRulesFromJsonString(rulesFileContents);
    rules->logRules();

    *rulesHandle  = rules;
    *rulesVersion = 0;
    return true;
}

// This function is part of the version-2 API:
ANGLE_EXPORT bool ANGLEGetSystemInfo(SystemInfoHandle *systemInfoHandle)
{
    if (!systemInfoHandle)
    {
        return false;
    }

    // TODO (http://anglebug.com/3036): Restore the real code
    angle::SystemInfo *systemInfo = new angle::SystemInfo;
    systemInfo->gpus.resize(1);
    GPUDeviceInfo &gpu = systemInfo->gpus[0];
    gpu.vendorId       = 0xFEFEFEFE;
    gpu.deviceId       = 0xFEEEFEEE;
    gpu.driverVendor   = "Foo";
    gpu.driverVersion  = "1.2.3.4";

    *systemInfoHandle = systemInfo;
    return true;
}

// This function is part of the version-2 API:
ANGLE_EXPORT bool ANGLEAddDeviceInfoToSystemInfo(const char *deviceMfr,
                                                 const char *deviceModel,
                                                 SystemInfoHandle systemInfoHandle)
{
    angle::SystemInfo *systemInfo = static_cast<angle::SystemInfo *>(systemInfoHandle);
    if (!deviceMfr || !deviceModel || !systemInfo)
    {
        return false;
    }

    systemInfo->machineManufacturer = deviceMfr;
    systemInfo->machineModelName    = deviceModel;
    return true;
}

// This function is part of the version-2 API:
ANGLE_EXPORT bool ANGLEShouldBeUsedForApplication(const RulesHandle rulesHandle,
                                                  int rulesVersion,
                                                  const SystemInfoHandle systemInfoHandle,
                                                  const char *appName)
{
    RuleList *rules               = static_cast<RuleList *>(rulesHandle);
    angle::SystemInfo *systemInfo = static_cast<angle::SystemInfo *>(systemInfoHandle);
    if (!rules || !systemInfo || !appName || (systemInfo->gpus.size() != 1))
    {
        return false;
    }

    Scenario scenario(appName, systemInfo->machineManufacturer.c_str(),
                      systemInfo->machineModelName.c_str());
    Version gpuDriverVersion(systemInfo->gpus[0].detailedDriverVersion.major,
                             systemInfo->gpus[0].detailedDriverVersion.minor,
                             systemInfo->gpus[0].detailedDriverVersion.subMinor,
                             systemInfo->gpus[0].detailedDriverVersion.patch);
    GPU gpuDriver(systemInfo->gpus[0].driverVendor, systemInfo->gpus[0].deviceId, gpuDriverVersion);
    scenario.mDevice.addGPU(gpuDriver);
    scenario.logScenario();

    bool rtn = rules->getUseANGLE(scenario);
    VERBOSE("Application \"%s\" should %s ANGLE", appName, rtn ? "use" : "NOT use");

    return rtn;
}

// This function is part of the version-2 API:
ANGLE_EXPORT void ANGLEFreeRulesHandle(const RulesHandle rulesHandle)
{
    RuleList *rules = static_cast<RuleList *>(rulesHandle);
    if (rules)
    {
        delete rules;
    }
}

// This function is part of the version-2 API:
ANGLE_EXPORT void ANGLEFreeSystemInfoHandle(const SystemInfoHandle systemInfoHandle)
{
    angle::SystemInfo *systemInfo = static_cast<angle::SystemInfo *>(systemInfoHandle);
    if (systemInfo)
    {
        delete systemInfo;
    }
}

}  // extern "C"
