/*
 * Copyright (C) 2015 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 <algorithm>
#include <iostream>
#include <sstream>

#include "Utilities.h"

using namespace std;

const char LEGAL_NOTICE[] =
            "/*\n"
            " * Copyright (C) 2016 The Android Open Source Project\n"
            " *\n"
            " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
            " * you may not use this file except in compliance with the License.\n"
            " * You may obtain a copy of the License at\n"
            " *\n"
            " *      http://www.apache.org/licenses/LICENSE-2.0\n"
            " *\n"
            " * Unless required by applicable law or agreed to in writing, software\n"
            " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
            " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
            " * See the License for the specific language governing permissions and\n"
            " * limitations under the License.\n"
            " */\n\n";

const char AUTO_GENERATED_WARNING[] =
            "Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.";

string capitalize(const string& source) {
    int length = source.length();
    string result;
    bool capitalize = true;
    for (int s = 0; s < length; s++) {
        if (source[s] == '_') {
            capitalize = true;
        } else if (capitalize) {
            result += toupper(source[s]);
            capitalize = false;
        } else {
            result += source[s];
        }
    }
    return result;
}

void trimSpaces(string* s) {
    const size_t end = s->find_last_not_of(" ");
    if (end == string::npos) {
        // All spaces
        s->erase();
        return;
    } else {
        s->erase(end + 1);
    }
    const size_t start = s->find_first_not_of(" ");
    if (start > 0) {
        s->erase(0, start);
    }
}

string stringReplace(string s, string match, string rep) {
    while (1) {
        // This is not efficient but we don't care, as this program runs very rarely.
        size_t p = s.find(match);
        if (p == string::npos) break;

        s.erase(p, match.size());
        s.insert(p, rep);
    }
    return s;
}

bool charRemoved(char c, string* s) {
    size_t p = s->find(c);
    if (p != string::npos) {
        s->erase(p, 1);
        return true;
    }
    return false;
}

string stripHtml(const string& html) {
    string in = stringReplace(html, "<li>", "- ");
    string out;
    for (size_t start = 0; start < in.size(); start++) {
        size_t lt = in.find('<', start);
        if (lt == string::npos) {
            out += in.substr(start);
            break;
        }
        out += in.substr(start, lt - start);
        if (isalpha(in[lt + 1]) || in[lt + 1] == '/') {
            // It's an HTML tag.  Search for the end.
            start = in.find('>', lt + 1);
            if (start == string::npos) {
                break;
            }
        } else {
            out += '<';
        }
    }
    out = stringReplace(out, "&gt;", ">");
    out = stringReplace(out, "&lt;", "<");
    out = stringReplace(out, "&nbsp;", " ");
    out = stringReplace(out, "&amp;", "&");
    return out;
}

string hashString(const string& s) {
    long hash = 0;
    for (size_t i = 0; i < s.length(); i++) {
        hash = hash * 43 + s[i];
    }
    stringstream stream;
    stream << "0x" << std::hex << hash << "l";
    return stream.str();
}

bool testAndSet(const string& flag, set<string>* set) {
    if (set->find(flag) == set->end()) {
        set->insert(flag);
        return false;
    }
    return true;
}

double maxDoubleForInteger(int numberOfIntegerBits, int mantissaSize) {
    /* Double has only 52 bits of precision (53 implied). So for longs, we want
     * to create smaller values to avoid a round up.  Same for floats and halfs.
     */
    int lowZeroBits = max(0, numberOfIntegerBits - mantissaSize);
    unsigned long l = (0xffffffffffffffff >> (64 - numberOfIntegerBits + lowZeroBits))
                      << lowZeroBits;
    return (double)l;
}

// Add the value to the stream, prefixed with a ", " if needed.
static void addCommaSeparated(const string& value, ostringstream* stream, bool* needComma) {
    if (value.empty()) {
        return;
    }
    if (*needComma) {
        *stream << ", ";
    }
    *stream << value;
    *needComma = true;
}

string makeAttributeTag(const string& userAttribute, const string& additionalAttribute,
                        unsigned int deprecatedApiLevel, const string& deprecatedMessage) {
    ostringstream stream;
    bool needComma = false;
    if (userAttribute[0] == '=') {
        /* If starts with an equal, we don't automatically add additionalAttribute.
         * This is because of the error we made defining rsUnpackColor8888().
         */
        addCommaSeparated(userAttribute.substr(1), &stream, &needComma);
    } else {
        addCommaSeparated(userAttribute, &stream, &needComma);
        addCommaSeparated(additionalAttribute, &stream, &needComma);
    }
    if (deprecatedApiLevel > 0) {
        stream << "\n#if (defined(RS_VERSION) && (RS_VERSION >= " << deprecatedApiLevel << "))\n";
        addCommaSeparated("deprecated", &stream, &needComma);
        if (!deprecatedMessage.empty()) {
            // Remove any @ that's used for generating documentation cross references.
            string s = deprecatedMessage;
            s.erase(std::remove(s.begin(), s.end(), '@'), s.end());
            stream << "(\"" << s << "\")";
        }
        stream << "\n#endif\n";
    }
    if (stream.tellp() == 0) {
        return "";
    }
    return " __attribute__((" + stream.str() + "))";
}

// Opens the stream.  Reports an error if it can't.
bool GeneratedFile::start(const string& directory, const string& name) {
    const string path = directory + "/" + name;
    open(path.c_str(), ios::out | ios::trunc);
    if (!is_open()) {
        cerr << "Error.  Can't open the output file: " << path << "\n";
        return false;
    }
    return true;
}

void GeneratedFile::writeNotices() {
    *this << LEGAL_NOTICE;
    *this << "// " << AUTO_GENERATED_WARNING << "\n\n";
}

void GeneratedFile::increaseIndent() {
    mIndent.append(string(TAB_SIZE, ' '));
}

void GeneratedFile::decreaseIndent() {
    mIndent.erase(0, TAB_SIZE);
}
