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

// Convert objects from and to strings.

#include "parse_string.h"
#include <android-base/parseint.h>

namespace android {
using base::ParseUint;

namespace vintf {

static const std::string kRequired("required");
static const std::string kOptional("optional");
static const std::string kConfigPrefix("CONFIG_");

std::vector<std::string> SplitString(const std::string &s, char c) {
    std::vector<std::string> components;

    size_t startPos = 0;
    size_t matchPos;
    while ((matchPos = s.find(c, startPos)) != std::string::npos) {
        components.push_back(s.substr(startPos, matchPos - startPos));
        startPos = matchPos + 1;
    }

    if (startPos <= s.length()) {
        components.push_back(s.substr(startPos));
    }
    return components;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> objs) {
    bool first = true;
    for (const T &v : objs) {
        if (!first) {
            os << ",";
        }
        os << v;
        first = false;
    }
    return os;
}

template <typename T>
bool parse(const std::string &s, std::vector<T> *objs) {
    std::vector<std::string> v = SplitString(s, ',');
    objs->resize(v.size());
    size_t idx = 0;
    for (const auto &item : v) {
        T ver;
        if (!parse(item, &ver)) {
            return false;
        }
        objs->at(idx++) = ver;
    }
    return true;
}

template<typename E, typename Array>
bool parseEnum(const std::string &s, E *e, const Array &strings) {
    for (size_t i = 0; i < strings.size(); ++i) {
        if (s == strings.at(i)) {
            *e = static_cast<E>(i);
            return true;
        }
    }
    return false;
}

#define DEFINE_PARSE_STREAMIN_FOR_ENUM(ENUM) \
    bool parse(const std::string &s, ENUM *hf) {                   \
        return parseEnum(s, hf, g##ENUM##Strings);                 \
    }                                                              \
    std::ostream &operator<<(std::ostream &os, ENUM hf) {          \
        return os << g##ENUM##Strings.at(static_cast<size_t>(hf)); \
    }                                                              \

DEFINE_PARSE_STREAMIN_FOR_ENUM(HalFormat);
DEFINE_PARSE_STREAMIN_FOR_ENUM(Transport);
DEFINE_PARSE_STREAMIN_FOR_ENUM(Arch);
DEFINE_PARSE_STREAMIN_FOR_ENUM(KernelConfigType);
DEFINE_PARSE_STREAMIN_FOR_ENUM(Tristate);
DEFINE_PARSE_STREAMIN_FOR_ENUM(SchemaType);
DEFINE_PARSE_STREAMIN_FOR_ENUM(XmlSchemaFormat);

std::ostream &operator<<(std::ostream &os, const KernelConfigTypedValue &kctv) {
    switch (kctv.mType) {
        case KernelConfigType::STRING:
            return os << kctv.mStringValue;
        case KernelConfigType::INTEGER:
            return os << to_string(kctv.mIntegerValue);
        case KernelConfigType::RANGE:
            return os << to_string(kctv.mRangeValue.first) << "-"
                      << to_string(kctv.mRangeValue.second);
        case KernelConfigType::TRISTATE:
            return os << to_string(kctv.mTristateValue);
    }
}

bool parse(const std::string& s, Level* l) {
    if (s.empty()) {
        *l = Level::UNSPECIFIED;
        return true;
    }
    if (s == "legacy") {
        *l = Level::LEGACY;
        return true;
    }
    size_t value;
    if (!ParseUint(s, &value)) {
        return false;
    }
    *l = static_cast<Level>(value);
    return true;
}

std::ostream& operator<<(std::ostream& os, Level l) {
    if (l == Level::UNSPECIFIED) {
        return os;
    }
    if (l == Level::LEGACY) {
        return os << "legacy";
    }
    return os << static_cast<size_t>(l);
}

// Notice that strtoull is used even though KernelConfigIntValue is signed int64_t,
// because strtoull can accept negative values as well.
// Notice that according to man strtoul, strtoull can actually accept
// -2^64 + 1 to 2^64 - 1, with the 65th bit truncated.
// ParseInt / ParseUint are not used because they do not handle signed hex very well.
template <typename T>
bool parseKernelConfigIntHelper(const std::string &s, T *i) {
    char *end;
    errno = 0;
    unsigned long long int ulli = strtoull(s.c_str(), &end, 0 /* base */);
    // It is implementation defined that what value will be returned by strtoull
    // in the error case, so we are checking errno directly here.
    if (errno == 0 && s.c_str() != end && *end == '\0') {
        *i = static_cast<T>(ulli);
        return true;
    }
    return false;
}

bool parseKernelConfigInt(const std::string &s, int64_t *i) {
    return parseKernelConfigIntHelper(s, i);
}

bool parseKernelConfigInt(const std::string &s, uint64_t *i) {
    return parseKernelConfigIntHelper(s, i);
}

bool parseRange(const std::string &s, KernelConfigRangeValue *range) {
    auto pos = s.find('-');
    if (pos == std::string::npos) {
        return false;
    }
    return parseKernelConfigInt(s.substr(0, pos),  &range->first)
        && parseKernelConfigInt(s.substr(pos + 1), &range->second);
}

bool parse(const std::string &s, KernelConfigKey *key) {
    *key = s;
    return true;
}

bool parseKernelConfigValue(const std::string &s, KernelConfigTypedValue *kctv) {
    switch (kctv->mType) {
        case KernelConfigType::STRING:
            kctv->mStringValue = s;
            return true;
        case KernelConfigType::INTEGER:
            return parseKernelConfigInt(s, &kctv->mIntegerValue);
        case KernelConfigType::RANGE:
            return parseRange(s, &kctv->mRangeValue);
        case KernelConfigType::TRISTATE:
            return parse(s, &kctv->mTristateValue);
    }
}

bool parseKernelConfigTypedValue(const std::string& s, KernelConfigTypedValue* kctv) {
    if (parseKernelConfigInt(s, &kctv->mIntegerValue)) {
        kctv->mType = KernelConfigType::INTEGER;
        return true;
    }
    if (parse(s, &kctv->mTristateValue)) {
        kctv->mType = KernelConfigType::TRISTATE;
        return true;
    }
    // Do not test for KernelConfigType::RANGE.
    kctv->mType = KernelConfigType::STRING;
    kctv->mStringValue = s;
    return true;
}

bool parse(const std::string &s, Version *ver) {
    std::vector<std::string> v = SplitString(s, '.');
    if (v.size() != 2) {
        return false;
    }
    size_t major, minor;
    if (!ParseUint(v[0], &major)) {
        return false;
    }
    if (!ParseUint(v[1], &minor)) {
        return false;
    }
    *ver = Version(major, minor);
    return true;
}

std::ostream &operator<<(std::ostream &os, const Version &ver) {
    return os << ver.majorVer << "." << ver.minorVer;
}

bool parse(const std::string &s, VersionRange *vr) {
    std::vector<std::string> v = SplitString(s, '-');
    if (v.size() != 1 && v.size() != 2) {
        return false;
    }
    Version minVer;
    if (!parse(v[0], &minVer)) {
        return false;
    }
    if (v.size() == 1) {
        *vr = VersionRange(minVer.majorVer, minVer.minorVer);
    } else {
        size_t maxMinor;
        if (!ParseUint(v[1], &maxMinor)) {
            return false;
        }
        *vr = VersionRange(minVer.majorVer, minVer.minorVer, maxMinor);
    }
    return true;
}

std::ostream &operator<<(std::ostream &os, const VersionRange &vr) {
    if (vr.isSingleVersion()) {
        return os << vr.minVer();
    }
    return os << vr.minVer() << "-" << vr.maxMinor;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
bool parse(const std::string &s, VndkVersionRange *vr) {
    std::vector<std::string> v = SplitString(s, '-');
    if (v.size() != 1 && v.size() != 2) {
        return false;
    }
    std::vector<std::string> minVector = SplitString(v[0], '.');
    if (minVector.size() != 3) {
        return false;
    }
    if (!ParseUint(minVector[0], &vr->sdk) ||
        !ParseUint(minVector[1], &vr->vndk) ||
        !ParseUint(minVector[2], &vr->patchMin)) {
        return false;
    }
    if (v.size() == 1) {
        vr->patchMax = vr->patchMin;
        return true;
    } else {
        return ParseUint(v[1], &vr->patchMax);
    }
}

std::ostream &operator<<(std::ostream &os, const VndkVersionRange &vr) {
    os << vr.sdk << "." << vr.vndk << "." << vr.patchMin;
    if (!vr.isSingleVersion()) {
        os << "-" << vr.patchMax;
    }
    return os;
}
#pragma clang diagnostic pop

bool parse(const std::string &s, KernelVersion *kernelVersion) {
    std::vector<std::string> v = SplitString(s, '.');
    if (v.size() != 3) {
        return false;
    }
    size_t version, major, minor;
    if (!ParseUint(v[0], &version)) {
        return false;
    }
    if (!ParseUint(v[1], &major)) {
        return false;
    }
    if (!ParseUint(v[2], &minor)) {
        return false;
    }
    *kernelVersion = KernelVersion(version, major, minor);
    return true;
}

std::ostream &operator<<(std::ostream &os, const TransportArch &ta) {
    return os << to_string(ta.transport) << to_string(ta.arch);
}

bool parse(const std::string &s, TransportArch *ta) {
    bool transportSet = false;
    bool archSet = false;
    for (size_t i = 0; i < gTransportStrings.size(); ++i) {
        if (s.find(gTransportStrings.at(i)) != std::string::npos) {
            ta->transport = static_cast<Transport>(i);
            transportSet = true;
            break;
        }
    }
    if (!transportSet) {
        return false;
    }
    for (size_t i = 0; i < gArchStrings.size(); ++i) {
        if (s.find(gArchStrings.at(i)) != std::string::npos) {
            ta->arch = static_cast<Arch>(i);
            archSet = true;
            break;
        }
    }
    if (!archSet) {
        return false;
    }
    return ta->isValid();
}

std::ostream &operator<<(std::ostream &os, const KernelVersion &ver) {
    return os << ver.version << "." << ver.majorRev << "." << ver.minorRev;
}

bool parse(const std::string &s, ManifestHal *hal) {
    std::vector<std::string> v = SplitString(s, '/');
    if (v.size() != 4) {
        return false;
    }
    if (!parse(v[0], &hal->format)) {
        return false;
    }
    hal->name = v[1];
    if (!parse(v[2], &hal->transportArch)) {
        return false;
    }
    if (!parse(v[3], &hal->versions)) {
        return false;
    }
    return hal->isValid();
}

std::ostream &operator<<(std::ostream &os, const ManifestHal &hal) {
    return os << hal.format << "/"
              << hal.name << "/"
              << hal.transportArch << "/"
              << hal.versions;
}

bool parse(const std::string &s, MatrixHal *req) {
    std::vector<std::string> v = SplitString(s, '/');
    if (v.size() != 4) {
        return false;
    }
    if (!parse(v[0], &req->format)) {
        return false;
    }
    req->name = v[1];
    if (!parse(v[2], &req->versionRanges)) {
        return false;
    }
    if (v[3] != kRequired || v[3] != kOptional) {
        return false;
    }
    req->optional = (v[3] == kOptional);
    return true;
}

std::ostream &operator<<(std::ostream &os, const MatrixHal &req) {
    return os << req.format << "/"
              << req.name << "/"
              << req.versionRanges << "/"
              << (req.optional ? kOptional : kRequired);
}

std::string expandInstances(const MatrixHal& req, const VersionRange& vr, bool brace) {
    std::string s;
    size_t count = 0;
    req.forEachInstance(vr, [&](const auto& matrixInstance) {
        if (count > 0) s += " AND ";
        s += toFQNameString(vr, matrixInstance.interface(),
                            matrixInstance.isRegex() ? matrixInstance.regexPattern()
                                                     : matrixInstance.exactInstance());
        count++;
        return true;
    });
    if (count == 0) {
        s += "@" + to_string(vr);
    }
    if (count >= 2 && brace) {
        s = "(" + s + ")";
    }
    return s;
}

std::vector<std::string> expandInstances(const MatrixHal& req) {
    size_t count = req.instancesCount();
    if (count == 0) {
        return {};
    }
    if (count == 1) {
        return {expandInstances(req, req.versionRanges.front(), false /* brace */)};
    }
    std::vector<std::string> ss;
    for (const auto& vr : req.versionRanges) {
        if (!ss.empty()) {
            ss.back() += " OR";
        }
        ss.push_back(expandInstances(req, vr, true /* brace */));
    }
    return ss;
}

std::ostream &operator<<(std::ostream &os, KernelSepolicyVersion ksv){
    return os << ksv.value;
}

bool parse(const std::string &s, KernelSepolicyVersion *ksv){
    return ParseUint(s, &ksv->value);
}

std::string dump(const HalManifest &vm) {
    std::ostringstream oss;
    bool first = true;
    for (const auto &hal : vm.getHals()) {
        if (!first) {
            oss << ":";
        }
        oss << hal;
        first = false;
    }
    return oss.str();
}

std::string dump(const RuntimeInfo& ki, bool verbose) {
    std::ostringstream oss;

    oss << "kernel = " << ki.osName() << "/" << ki.nodeName() << "/" << ki.osRelease() << "/"
        << ki.osVersion() << "/" << ki.hardwareId() << ";" << ki.mBootAvbVersion << "/"
        << ki.mBootVbmetaAvbVersion << ";"
        << "kernelSepolicyVersion = " << ki.kernelSepolicyVersion() << ";";

    if (verbose) {
        oss << "\n\ncpu info:\n" << ki.cpuInfo();
    }

    oss << "\n#CONFIG's loaded = " << ki.mKernelConfigs.size() << ";\n";

    if (verbose) {
        for (const auto& pair : ki.mKernelConfigs) {
            oss << pair.first << "=" << pair.second << "\n";
        }
    }

    return oss.str();
}

std::string toFQNameString(const std::string& package, const std::string& version,
                           const std::string& interface, const std::string& instance) {
    std::stringstream ss;
    ss << package << "@" << version;
    if (!interface.empty()) {
        ss << "::" << interface;
        if (!instance.empty()) {
            ss << "/" << instance;
        }
    }
    return ss.str();
}

std::string toFQNameString(const std::string& package, const Version& version,
                           const std::string& interface, const std::string& instance) {
    return toFQNameString(package, to_string(version), interface, instance);
}

std::string toFQNameString(const Version& version, const std::string& interface,
                           const std::string& instance) {
    return toFQNameString("", version, interface, instance);
}

// android.hardware.foo@1.0-1::IFoo/default.
// Note that the format is extended to support a range of versions.
std::string toFQNameString(const std::string& package, const VersionRange& range,
                           const std::string& interface, const std::string& instance) {
    return toFQNameString(package, to_string(range), interface, instance);
}

std::string toFQNameString(const VersionRange& range, const std::string& interface,
                           const std::string& instance) {
    return toFQNameString("", range, interface, instance);
}

std::ostream& operator<<(std::ostream& os, const FqInstance& fqInstance) {
    return os << fqInstance.string();
}

bool parse(const std::string& s, FqInstance* fqInstance) {
    return fqInstance->setTo(s);
}

} // namespace vintf
} // namespace android
