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

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

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

    return out;
}

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

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

    return out;
}

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

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

    return out;
}

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

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

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

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, "_");
}

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, "_");
}

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

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

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

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

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

    return in;
}

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

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

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

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

