/*
 * Copyright (C) 2016 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 "StringHelper.h"

#include <sstream>
#include <regex>

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

#define UPPERCASE  "[A-Z0-9]+"
#define LOWERCASE "[a-z0-9]+"
#define CAPCASE "[A-Z0-9][a-z0-9]*"
static const std::regex kStartUppercase("^" UPPERCASE);
static const std::regex kStartLowercase("^" LOWERCASE);
static const std::regex kStartCapcase("^" CAPCASE);

namespace android {

// static
std::string StringHelper::Uppercase(const std::string &in) {
    std::string out{in};

    for (auto &ch : out) {
        ch = toupper(ch);
    }

    return out;
}

// static
std::string StringHelper::Lowercase(const std::string &in) {
    std::string out{in};

    for (auto &ch : out) {
        ch = tolower(ch);
    }

    return out;
}

// static
std::string StringHelper::Capitalize(const std::string &in) {
    std::string out{in};

    if(!out.empty()) {
        out[0] = toupper(out[0]);
    }

    return out;
}

// static
void StringHelper::Tokenize(const std::string &in,
        std::vector<std::string> *vec) {

    std::smatch match;
    if (in.empty()) {
        vec->clear();
        return;
    }
    std::string copy(in);
    vec->clear();
    std::vector<std::string> matches;

    copy = RTrimAll(copy, "_");
    while(!copy.empty()) {
        copy = LTrimAll(copy, "_");
        if (std::regex_search(copy, match, kStartLowercase))
            matches.push_back(match.str(0));
        if (std::regex_search(copy, match, kStartCapcase))
            matches.push_back(match.str(0));
        if (std::regex_search(copy, match, kStartUppercase))
            matches.push_back(match.str(0));
        if (!matches.empty()) {
            std::string &maxmatch = matches[0];
            for (std::string &match : matches)
                if(match.length() > maxmatch.length())
                    maxmatch = match;
            vec->push_back(maxmatch);
            copy = copy.substr(maxmatch.length());
            matches.clear();
            continue;
        }
        LOG(WARNING) << "Could not stylize \"" << in << "\"";
        // don't know what to do, so push back the rest of the string.
        vec->push_back(copy);
    }
}

// static
std::string StringHelper::ToCamelCase(const std::string &in) {
    std::vector<std::string> components;
    Tokenize(in, &components);
    if (components.empty()) {
        if (!in.empty())
            LOG(WARNING) << "Could not stylize \"" << in << "\"";
        return in;
    }
    components[0] = Lowercase(components[0]);
    for (size_t i = 1; i < components.size(); i++) {
        components[i] = Capitalize(components[i]);
    }
    return JoinStrings(components, "");
}

// static
std::string StringHelper::ToPascalCase(const std::string &in) {
    std::vector<std::string> components;
    Tokenize(in, &components);
    for (size_t i = 0; i < components.size(); i++) {
        components[i] = Capitalize(components[i]);
    }
    return JoinStrings(components, "");
}

// static
std::string StringHelper::ToUpperSnakeCase(const std::string &in) {
    std::vector<std::string> components;
    Tokenize(in, &components);
    for (size_t i = 0; i < components.size(); i++) {
        components[i] = Uppercase(components[i]);
    }
    return JoinStrings(components, "_");
}

// static
std::string StringHelper::ToLowerSnakeCase(const std::string &in) {
    std::vector<std::string> components;
    Tokenize(in, &components);
    for (size_t i = 0; i < components.size(); i++) {
        components[i] = Lowercase(components[i]);
    }
    return JoinStrings(components, "_");
}

// static
std::string StringHelper::ToCase(StringHelper::Case c, const std::string &in) {
    switch(c) {
    case kCamelCase:
        return ToCamelCase(in);
    case kPascalCase:
        return ToPascalCase(in);
    case kUpperSnakeCase:
        return ToUpperSnakeCase(in);
    case kLowerSnakeCase:
        return ToLowerSnakeCase(in);
    case kNoCase:
        return in;
    }
    LOG(FATAL) << "Should not reach here.";
    return in;
}

// static
bool StringHelper::EndsWith(const std::string &in, const std::string &suffix) {
    return in.size() >= suffix.size() &&
           in.substr(in.size() - suffix.size()) == suffix;
}

// static
bool StringHelper::StartsWith(const std::string &in, const std::string &prefix) {
    return in.size() >= prefix.size() &&
           in.substr(0, prefix.size()) == prefix;
}

// static
std::string StringHelper::RTrim(const std::string &in, const std::string &suffix) {
    if (EndsWith(in, suffix)) {
        return in.substr(0, in.size() - suffix.size());
    }

    return in;
}

// static
std::string StringHelper::LTrim(const std::string &in, const std::string &prefix) {
    if (StartsWith(in, prefix)) {
        return in.substr(prefix.size());
    }

    return in;
}

// static
std::string StringHelper::RTrimAll(const std::string &in, const std::string &suffix) {
    std::string copy(in);
    while (EndsWith(copy, suffix)) {
        copy = copy.substr(0, copy.size() - suffix.size());
    }

    return copy;
}

// static
std::string StringHelper::LTrimAll(const std::string &in, const std::string &prefix) {
    std::string copy(in);
    while (StartsWith(copy, prefix)) {
        copy = copy.substr(prefix.size());
    }

    return copy;
}

// static
void StringHelper::SplitString(
        const std::string &s, char c, std::vector<std::string> *components) {
    components->clear();

    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));
    }
}

// static
std::string StringHelper::JoinStrings(
        const std::vector<std::string> &components,
        const std::string &separator) {
    std::string out;
    bool first = true;
    for (const auto &component : components) {
        if (!first) {
            out += separator;
        }
        out += component;

        first = false;
    }

    return out;
}

}  // namespace android

