/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/sksl/SkSLOperator.h"

#include "include/core/SkTypes.h"
#include "include/private/SkStringView.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLType.h"

#include <memory>

namespace SkSL {

OperatorPrecedence Operator::getBinaryPrecedence() const {
    switch (this->kind()) {
        case Kind::STAR:         // fall through
        case Kind::SLASH:        // fall through
        case Kind::PERCENT:      return OperatorPrecedence::kMultiplicative;
        case Kind::PLUS:         // fall through
        case Kind::MINUS:        return OperatorPrecedence::kAdditive;
        case Kind::SHL:          // fall through
        case Kind::SHR:          return OperatorPrecedence::kShift;
        case Kind::LT:           // fall through
        case Kind::GT:           // fall through
        case Kind::LTEQ:         // fall through
        case Kind::GTEQ:         return OperatorPrecedence::kRelational;
        case Kind::EQEQ:         // fall through
        case Kind::NEQ:          return OperatorPrecedence::kEquality;
        case Kind::BITWISEAND:   return OperatorPrecedence::kBitwiseAnd;
        case Kind::BITWISEXOR:   return OperatorPrecedence::kBitwiseXor;
        case Kind::BITWISEOR:    return OperatorPrecedence::kBitwiseOr;
        case Kind::LOGICALAND:   return OperatorPrecedence::kLogicalAnd;
        case Kind::LOGICALXOR:   return OperatorPrecedence::kLogicalXor;
        case Kind::LOGICALOR:    return OperatorPrecedence::kLogicalOr;
        case Kind::EQ:           // fall through
        case Kind::PLUSEQ:       // fall through
        case Kind::MINUSEQ:      // fall through
        case Kind::STAREQ:       // fall through
        case Kind::SLASHEQ:      // fall through
        case Kind::PERCENTEQ:    // fall through
        case Kind::SHLEQ:        // fall through
        case Kind::SHREQ:        // fall through
        case Kind::BITWISEANDEQ: // fall through
        case Kind::BITWISEXOREQ: // fall through
        case Kind::BITWISEOREQ:  return OperatorPrecedence::kAssignment;
        case Kind::COMMA:        return OperatorPrecedence::kSequence;
        default: SK_ABORT("unsupported binary operator");
    }
}

const char* Operator::operatorName() const {
    switch (this->kind()) {
        case Kind::PLUS:         return " + ";
        case Kind::MINUS:        return " - ";
        case Kind::STAR:         return " * ";
        case Kind::SLASH:        return " / ";
        case Kind::PERCENT:      return " % ";
        case Kind::SHL:          return " << ";
        case Kind::SHR:          return " >> ";
        case Kind::LOGICALNOT:   return "!";
        case Kind::LOGICALAND:   return " && ";
        case Kind::LOGICALOR:    return " || ";
        case Kind::LOGICALXOR:   return " ^^ ";
        case Kind::BITWISENOT:   return "~";
        case Kind::BITWISEAND:   return " & ";
        case Kind::BITWISEOR:    return " | ";
        case Kind::BITWISEXOR:   return " ^ ";
        case Kind::EQ:           return " = ";
        case Kind::EQEQ:         return " == ";
        case Kind::NEQ:          return " != ";
        case Kind::LT:           return " < ";
        case Kind::GT:           return " > ";
        case Kind::LTEQ:         return " <= ";
        case Kind::GTEQ:         return " >= ";
        case Kind::PLUSEQ:       return " += ";
        case Kind::MINUSEQ:      return " -= ";
        case Kind::STAREQ:       return " *= ";
        case Kind::SLASHEQ:      return " /= ";
        case Kind::PERCENTEQ:    return " %= ";
        case Kind::SHLEQ:        return " <<= ";
        case Kind::SHREQ:        return " >>= ";
        case Kind::BITWISEANDEQ: return " &= ";
        case Kind::BITWISEOREQ:  return " |= ";
        case Kind::BITWISEXOREQ: return " ^= ";
        case Kind::PLUSPLUS:     return "++";
        case Kind::MINUSMINUS:   return "--";
        case Kind::COMMA:        return ", ";
        default: SkUNREACHABLE;
    }
}

std::string_view Operator::tightOperatorName() const {
    std::string_view name = this->operatorName();
    if (skstd::starts_with(name, ' ')) {
        name.remove_prefix(1);
    }
    if (skstd::ends_with(name, ' ')) {
        name.remove_suffix(1);
    }
    return name;
}

bool Operator::isAssignment() const {
    switch (this->kind()) {
        case Kind::EQ:           // fall through
        case Kind::PLUSEQ:       // fall through
        case Kind::MINUSEQ:      // fall through
        case Kind::STAREQ:       // fall through
        case Kind::SLASHEQ:      // fall through
        case Kind::PERCENTEQ:    // fall through
        case Kind::SHLEQ:        // fall through
        case Kind::SHREQ:        // fall through
        case Kind::BITWISEOREQ:  // fall through
        case Kind::BITWISEXOREQ: // fall through
        case Kind::BITWISEANDEQ:
            return true;
        default:
            return false;
    }
}

Operator Operator::removeAssignment() const {
    switch (this->kind()) {
        case Kind::PLUSEQ:       return Kind::PLUS;
        case Kind::MINUSEQ:      return Kind::MINUS;
        case Kind::STAREQ:       return Kind::STAR;
        case Kind::SLASHEQ:      return Kind::SLASH;
        case Kind::PERCENTEQ:    return Kind::PERCENT;
        case Kind::SHLEQ:        return Kind::SHL;
        case Kind::SHREQ:        return Kind::SHR;
        case Kind::BITWISEOREQ:  return Kind::BITWISEOR;
        case Kind::BITWISEXOREQ: return Kind::BITWISEXOR;
        case Kind::BITWISEANDEQ: return Kind::BITWISEAND;
        default: return *this;
    }
}

bool Operator::isRelational() const {
    switch (this->kind()) {
        case Kind::LT:
        case Kind::GT:
        case Kind::LTEQ:
        case Kind::GTEQ:
            return true;
        default:
            return false;
    }
}

bool Operator::isOnlyValidForIntegralTypes() const {
    switch (this->kind()) {
        case Kind::SHL:
        case Kind::SHR:
        case Kind::BITWISEAND:
        case Kind::BITWISEOR:
        case Kind::BITWISEXOR:
        case Kind::PERCENT:
        case Kind::SHLEQ:
        case Kind::SHREQ:
        case Kind::BITWISEANDEQ:
        case Kind::BITWISEOREQ:
        case Kind::BITWISEXOREQ:
        case Kind::PERCENTEQ:
            return true;
        default:
            return false;
    }
}

bool Operator::isValidForMatrixOrVector() const {
    switch (this->kind()) {
        case Kind::PLUS:
        case Kind::MINUS:
        case Kind::STAR:
        case Kind::SLASH:
        case Kind::PERCENT:
        case Kind::SHL:
        case Kind::SHR:
        case Kind::BITWISEAND:
        case Kind::BITWISEOR:
        case Kind::BITWISEXOR:
        case Kind::PLUSEQ:
        case Kind::MINUSEQ:
        case Kind::STAREQ:
        case Kind::SLASHEQ:
        case Kind::PERCENTEQ:
        case Kind::SHLEQ:
        case Kind::SHREQ:
        case Kind::BITWISEANDEQ:
        case Kind::BITWISEOREQ:
        case Kind::BITWISEXOREQ:
            return true;
        default:
            return false;
    }
}

bool Operator::isMatrixMultiply(const Type& left, const Type& right) const {
    if (this->kind() != Kind::STAR && this->kind() != Kind::STAREQ) {
        return false;
    }
    if (left.isMatrix()) {
        return right.isMatrix() || right.isVector();
    }
    return left.isVector() && right.isMatrix();
}

/**
 * Determines the operand and result types of a binary expression. Returns true if the expression is
 * legal, false otherwise. If false, the values of the out parameters are undefined.
 */
bool Operator::determineBinaryType(const Context& context,
                                   const Type& left,
                                   const Type& right,
                                   const Type** outLeftType,
                                   const Type** outRightType,
                                   const Type** outResultType) const {
    const bool allowNarrowing = context.fConfig->fSettings.fAllowNarrowingConversions;
    switch (this->kind()) {
        case Kind::EQ:  // left = right
            if (left.isVoid()) {
                return false;
            }
            *outLeftType = &left;
            *outRightType = &left;
            *outResultType = &left;
            return right.canCoerceTo(left, allowNarrowing);

        case Kind::EQEQ:   // left == right
        case Kind::NEQ: {  // left != right
            if (left.isVoid() || left.isOpaque()) {
                return false;
            }
            CoercionCost rightToLeft = right.coercionCost(left),
                         leftToRight = left.coercionCost(right);
            if (rightToLeft < leftToRight) {
                if (rightToLeft.isPossible(allowNarrowing)) {
                    *outLeftType = &left;
                    *outRightType = &left;
                    *outResultType = context.fTypes.fBool.get();
                    return true;
                }
            } else {
                if (leftToRight.isPossible(allowNarrowing)) {
                    *outLeftType = &right;
                    *outRightType = &right;
                    *outResultType = context.fTypes.fBool.get();
                    return true;
                }
            }
            return false;
        }
        case Kind::LOGICALOR:   // left || right
        case Kind::LOGICALAND:  // left && right
        case Kind::LOGICALXOR:  // left ^^ right
            *outLeftType = context.fTypes.fBool.get();
            *outRightType = context.fTypes.fBool.get();
            *outResultType = context.fTypes.fBool.get();
            return left.canCoerceTo(*context.fTypes.fBool, allowNarrowing) &&
                   right.canCoerceTo(*context.fTypes.fBool, allowNarrowing);

        case Operator::Kind::COMMA:  // left, right
            if (left.isOpaque() || right.isOpaque()) {
                return false;
            }
            *outLeftType = &left;
            *outRightType = &right;
            *outResultType = &right;
            return true;

        default:
            break;
    }

    // Boolean types only support the operators listed above (, = == != || && ^^).
    // If we've gotten this far with a boolean, we have an unsupported operator.
    const Type& leftComponentType = left.componentType();
    const Type& rightComponentType = right.componentType();
    if (leftComponentType.isBoolean() || rightComponentType.isBoolean()) {
        return false;
    }

    bool isAssignment = this->isAssignment();
    if (this->isMatrixMultiply(left, right)) {  // left * right
        // Determine final component type.
        if (!this->determineBinaryType(context, left.componentType(), right.componentType(),
                                       outLeftType, outRightType, outResultType)) {
            return false;
        }
        // Convert component type to compound.
        *outLeftType = &(*outResultType)->toCompound(context, left.columns(), left.rows());
        *outRightType = &(*outResultType)->toCompound(context, right.columns(), right.rows());
        int leftColumns = left.columns(), leftRows = left.rows();
        int rightColumns = right.columns(), rightRows = right.rows();
        if (right.isVector()) {
            // `matrix * vector` treats the vector as a column vector; we need to transpose it.
            std::swap(rightColumns, rightRows);
            SkASSERT(rightColumns == 1);
        }
        if (rightColumns > 1) {
            *outResultType = &(*outResultType)->toCompound(context, rightColumns, leftRows);
        } else {
            // The result was a column vector. Transpose it back to a row.
            *outResultType = &(*outResultType)->toCompound(context, leftRows, rightColumns);
        }
        if (isAssignment && ((*outResultType)->columns() != leftColumns ||
                             (*outResultType)->rows() != leftRows)) {
            return false;
        }
        return leftColumns == rightRows;
    }

    bool leftIsVectorOrMatrix = left.isVector() || left.isMatrix();
    bool validMatrixOrVectorOp = this->isValidForMatrixOrVector();

    if (leftIsVectorOrMatrix && validMatrixOrVectorOp && right.isScalar()) {
        // Determine final component type.
        if (!this->determineBinaryType(context, left.componentType(), right,
                                       outLeftType, outRightType, outResultType)) {
            return false;
        }
        // Convert component type to compound.
        *outLeftType = &(*outLeftType)->toCompound(context, left.columns(), left.rows());
        if (!this->isRelational()) {
            *outResultType = &(*outResultType)->toCompound(context, left.columns(), left.rows());
        }
        return true;
    }

    bool rightIsVectorOrMatrix = right.isVector() || right.isMatrix();

    if (!isAssignment && rightIsVectorOrMatrix && validMatrixOrVectorOp && left.isScalar()) {
        // Determine final component type.
        if (!this->determineBinaryType(context, left, right.componentType(),
                                       outLeftType, outRightType, outResultType)) {
            return false;
        }
        // Convert component type to compound.
        *outRightType = &(*outRightType)->toCompound(context, right.columns(), right.rows());
        if (!this->isRelational()) {
            *outResultType = &(*outResultType)->toCompound(context, right.columns(), right.rows());
        }
        return true;
    }

    CoercionCost rightToLeftCost = right.coercionCost(left);
    CoercionCost leftToRightCost = isAssignment ? CoercionCost::Impossible()
                                                : left.coercionCost(right);

    if ((left.isScalar() && right.isScalar()) || (leftIsVectorOrMatrix && validMatrixOrVectorOp)) {
        if (this->isOnlyValidForIntegralTypes()) {
            if (!leftComponentType.isInteger() || !rightComponentType.isInteger()) {
                return false;
            }
        }
        if (rightToLeftCost.isPossible(allowNarrowing) && rightToLeftCost < leftToRightCost) {
            // Right-to-Left conversion is possible and cheaper
            *outLeftType = &left;
            *outRightType = &left;
            *outResultType = &left;
        } else if (leftToRightCost.isPossible(allowNarrowing)) {
            // Left-to-Right conversion is possible (and at least as cheap as Right-to-Left)
            *outLeftType = &right;
            *outRightType = &right;
            *outResultType = &right;
        } else {
            return false;
        }
        if (this->isRelational()) {
            *outResultType = context.fTypes.fBool.get();
        }
        return true;
    }
    return false;
}

}  // namespace SkSL
