/*
 * 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 (s.size() > 1 && s[0] == '"' && s.back() == '"') {
        kctv->mType = KernelConfigType::STRING;
        kctv->mStringValue = s.substr(1, s.size()-2);
        return true;
    }
    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.
    return false;
}

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
