/*
 * 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 "PathParser.h"

#include "jni.h"

#include <errno.h>
#include <stdlib.h>
#include <utils/Log.h>
#include <sstream>
#include <string>
#include <vector>

namespace android {
namespace uirenderer {

static size_t nextStart(const char* s, size_t length, size_t startIndex) {
    size_t index = startIndex;
    while (index < length) {
        char c = s[index];
        // Note that 'e' or 'E' are not valid path commands, but could be
        // used for floating point numbers' scientific notation.
        // Therefore, when searching for next command, we should ignore 'e'
        // and 'E'.
        if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0)) && c != 'e' &&
            c != 'E') {
            return index;
        }
        index++;
    }
    return index;
}

/**
 * Calculate the position of the next comma or space or negative sign
 * @param s the string to search
 * @param start the position to start searching
 * @param result the result of the extraction, including the position of the
 * the starting position of next number, whether it is ending with a '-'.
 */
static void extract(int* outEndPosition, bool* outEndWithNegOrDot, const char* s, int start,
                    int end) {
    // Now looking for ' ', ',', '.' or '-' from the start.
    int currentIndex = start;
    bool foundSeparator = false;
    *outEndWithNegOrDot = false;
    bool secondDot = false;
    bool isExponential = false;
    for (; currentIndex < end; currentIndex++) {
        bool isPrevExponential = isExponential;
        isExponential = false;
        char currentChar = s[currentIndex];
        switch (currentChar) {
            case ' ':
            case ',':
                foundSeparator = true;
                break;
            case '-':
                // The negative sign following a 'e' or 'E' is not a separator.
                if (currentIndex != start && !isPrevExponential) {
                    foundSeparator = true;
                    *outEndWithNegOrDot = true;
                }
                break;
            case '.':
                if (!secondDot) {
                    secondDot = true;
                } else {
                    // This is the second dot, and it is considered as a separator.
                    foundSeparator = true;
                    *outEndWithNegOrDot = true;
                }
                break;
            case 'e':
            case 'E':
                isExponential = true;
                break;
        }
        if (foundSeparator) {
            break;
        }
    }
    // In the case where nothing is found, we put the end position to the end of
    // our extract range. Otherwise, end position will be where separator is found.
    *outEndPosition = currentIndex;
}

static float parseFloat(PathParser::ParseResult* result, const char* startPtr,
                        size_t expectedLength) {
    char* endPtr = NULL;
    float currentValue = strtof(startPtr, &endPtr);
    if ((currentValue == HUGE_VALF || currentValue == -HUGE_VALF) && errno == ERANGE) {
        result->failureOccurred = true;
        result->failureMessage = "Float out of range:  ";
        result->failureMessage.append(startPtr, expectedLength);
    }
    if (currentValue == 0 && endPtr == startPtr) {
        // No conversion is done.
        result->failureOccurred = true;
        result->failureMessage = "Float format error when parsing: ";
        result->failureMessage.append(startPtr, expectedLength);
    }
    return currentValue;
}

/**
 * Parse the floats in the string.
 *
 * @param s the string containing a command and list of floats
 * @return true on success
 */
static void getFloats(std::vector<float>* outPoints, PathParser::ParseResult* result,
                      const char* pathStr, int start, int end) {
    if (pathStr[start] == 'z' || pathStr[start] == 'Z') {
        return;
    }
    int startPosition = start + 1;
    int endPosition = start;

    // The startPosition should always be the first character of the
    // current number, and endPosition is the character after the current
    // number.
    while (startPosition < end) {
        bool endWithNegOrDot;
        extract(&endPosition, &endWithNegOrDot, pathStr, startPosition, end);

        if (startPosition < endPosition) {
            float currentValue = parseFloat(result, &pathStr[startPosition], end - startPosition);
            if (result->failureOccurred) {
                return;
            }
            outPoints->push_back(currentValue);
        }

        if (endWithNegOrDot) {
            // Keep the '-' or '.' sign with next number.
            startPosition = endPosition;
        } else {
            startPosition = endPosition + 1;
        }
    }
    return;
}

void PathParser::validateVerbAndPoints(char verb, size_t points, PathParser::ParseResult* result) {
    size_t numberOfPointsExpected = -1;
    switch (verb) {
        case 'z':
        case 'Z':
            numberOfPointsExpected = 0;
            break;
        case 'm':
        case 'l':
        case 't':
        case 'M':
        case 'L':
        case 'T':
            numberOfPointsExpected = 2;
            break;
        case 'h':
        case 'v':
        case 'H':
        case 'V':
            numberOfPointsExpected = 1;
            break;
        case 'c':
        case 'C':
            numberOfPointsExpected = 6;
            break;
        case 's':
        case 'q':
        case 'S':
        case 'Q':
            numberOfPointsExpected = 4;
            break;
        case 'a':
        case 'A':
            numberOfPointsExpected = 7;
            break;
        default:
            result->failureOccurred = true;
            result->failureMessage += verb;
            result->failureMessage += " is not a valid verb. ";
            return;
    }
    if (numberOfPointsExpected == 0 && points == 0) {
        return;
    }
    if (numberOfPointsExpected > 0 && points % numberOfPointsExpected == 0) {
        return;
    }

    result->failureOccurred = true;
    result->failureMessage += verb;
    result->failureMessage += " needs to be followed by ";
    if (numberOfPointsExpected > 0) {
        result->failureMessage += "a multiple of ";
    }
    result->failureMessage += std::to_string(numberOfPointsExpected)
            + " floats. However, " + std::to_string(points)
            + " float(s) are found. ";
}

void PathParser::getPathDataFromAsciiString(PathData* data, ParseResult* result,
                                            const char* pathStr, size_t strLen) {
    if (pathStr == NULL) {
        result->failureOccurred = true;
        result->failureMessage = "Path string cannot be NULL.";
        return;
    }

    size_t start = 0;
    // Skip leading spaces.
    while (isspace(pathStr[start]) && start < strLen) {
        start++;
    }
    if (start == strLen) {
        result->failureOccurred = true;
        result->failureMessage = "Path string cannot be empty.";
        return;
    }
    size_t end = start + 1;

    while (end < strLen) {
        end = nextStart(pathStr, strLen, end);
        std::vector<float> points;
        getFloats(&points, result, pathStr, start, end);
        validateVerbAndPoints(pathStr[start], points.size(), result);
        if (result->failureOccurred) {
            // If either verb or points is not valid, return immediately.
            result->failureMessage += "Failure occurred at position " +
                                     std::to_string(start) + " of path: " + pathStr;
            return;
        }
        data->verbs.push_back(pathStr[start]);
        data->verbSizes.push_back(points.size());
        data->points.insert(data->points.end(), points.begin(), points.end());
        start = end;
        end++;
    }

    if ((end - start) == 1 && start < strLen) {
        validateVerbAndPoints(pathStr[start], 0, result);
        if (result->failureOccurred) {
            // If either verb or points is not valid, return immediately.
            result->failureMessage += "Failure occurred at position " +
                                     std::to_string(start) + " of path: " + pathStr;
            return;
        }
        data->verbs.push_back(pathStr[start]);
        data->verbSizes.push_back(0);
    }
}

void PathParser::dump(const PathData& data) {
    // Print out the path data.
    size_t start = 0;
    for (size_t i = 0; i < data.verbs.size(); i++) {
        std::ostringstream os;
        os << data.verbs[i];
        os << ", verb size: " << data.verbSizes[i];
        for (size_t j = 0; j < data.verbSizes[i]; j++) {
            os << " " << data.points[start + j];
        }
        start += data.verbSizes[i];
        ALOGD("%s", os.str().c_str());
    }

    std::ostringstream os;
    for (size_t i = 0; i < data.points.size(); i++) {
        os << data.points[i] << ", ";
    }
    ALOGD("points are : %s", os.str().c_str());
}

void PathParser::parseAsciiStringForSkPath(SkPath* skPath, ParseResult* result, const char* pathStr,
                                           size_t strLen) {
    PathData pathData;
    getPathDataFromAsciiString(&pathData, result, pathStr, strLen);
    if (result->failureOccurred) {
        return;
    }
    // Check if there is valid data coming out of parsing the string.
    if (pathData.verbs.size() == 0) {
        result->failureOccurred = true;
        result->failureMessage = "No verbs found in the string for pathData: ";
        result->failureMessage += pathStr;
        return;
    }
    VectorDrawableUtils::verbsToPath(skPath, pathData);
    return;
}

};  // namespace uirenderer
};  // namespace android
