/*
 * 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 "Expression.h"
#include "Define.h"
#include "AST.h"
#include "Scope.h"

#include <vector>
#include <regex>

namespace android {

static const std::regex RE_S32("[^ul]$");
static const std::regex RE_U32("[^ul]u$");
static const std::regex RE_S64("[^ul](l|ll)$");
static const std::regex RE_U64("[^ul](ul|ull)$");

// static
Expression::Type Expression::integralType(std::string integer) {
    if (std::regex_search(integer, RE_S32)) {
        return Type::S32;
    }

    if (std::regex_search(integer, RE_U32)) {
        return Type::U32;
    }

    if (std::regex_search(integer, RE_S64)) {
        return Type::S64;
    }

    if (std::regex_search(integer, RE_U64)) {
        return Type::U64;
    }

    LOG(WARNING) << "UNKNOWN INTEGER LITERAL: " << integer;

    return Type::UNKNOWN;
}

// static
Expression::Type Expression::coalesceTypes(Type lhs, Type rhs) {
    // because we are reducing everything to two ranks, we can heavily simplify
    // conversion rules

#define SIGNED(i) (i & 2) // i & 0b10
#define MAX_RANK(i) (i | 1) // i | 0b01

    if (lhs == rhs) {
        return lhs;
    }

    // lhs != rhs
    if (SIGNED(lhs) == SIGNED(rhs)) {
        return (Type)MAX_RANK(lhs);
    }

    // lhs != rhs && SIGNED(lhs) != SIGNED(rhs)
    if (lhs == U32 || rhs == U32) {
        return S64;
    }

    return Type::UNKNOWN;

#undef SIGNED
#undef MAX_RANK

}

struct ParenthesizedExpression : Expression {
    ParenthesizedExpression(Expression* inner)
    : mInner(inner) {}
    ~ParenthesizedExpression() {
        delete mInner;
    }

    virtual Type getType(const AST &ast) {
        return mInner->getType(ast);
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        return "(" + mInner->toString(atomCase) + ")";
    }

private:
    Expression* mInner;

    DISALLOW_COPY_AND_ASSIGN(ParenthesizedExpression);
};

struct AtomExpression : Expression {
    AtomExpression(Type type, const std::string &value, bool isId)
    : mType(type), mValue(value), mIsId(isId)
    {}

    virtual Type getType(const AST &ast) {
        if (mType != Type::UNKNOWN) {
            return mType;
        }

        Define *define = ast.getDefinesScope().lookup(mValue);

        if (define == NULL) {
            return Type::UNKNOWN;
        }

        return define->getExpressionType();
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        // do not enforce case if it is not an identifier.
        return mIsId ? StringHelper::ToCase(atomCase, mValue) : mValue;
    }

private:
    Type mType;
    std::string mValue;
    bool mIsId;

    DISALLOW_COPY_AND_ASSIGN(AtomExpression);
};

struct UnaryExpression : Expression {
    UnaryExpression(std::string op, Expression* rhs)
    : mOp(op), mRhs(rhs)
    {}
    ~UnaryExpression() {
        delete mRhs;
    }

    virtual Type getType(const AST &ast) {
        return mRhs->getType(ast);
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        return mOp + mRhs->toString(atomCase);
    }

private:
    std::string mOp;
    Expression* mRhs;

    DISALLOW_COPY_AND_ASSIGN(UnaryExpression);
};

struct BinaryExpression : Expression {
    BinaryExpression(Expression *lhs, std::string op, Expression* rhs)
    : mLhs(lhs), mOp(op), mRhs(rhs)
    {}
    ~BinaryExpression() {
        delete mLhs;
        delete mRhs;
    }

    virtual Type getType(const AST &ast) {
        return coalesceTypes(mLhs->getType(ast), mRhs->getType(ast));
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        return mLhs->toString(atomCase) + " " + mOp + " " + mRhs->toString(atomCase);
    }

private:
    Expression* mLhs;
    std::string mOp;
    Expression* mRhs;

    DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
};

struct TernaryExpression : Expression {
    TernaryExpression(Expression *lhs, Expression *mhs, Expression* rhs)
    : mLhs(lhs), mMhs(mhs), mRhs(rhs)
    {}
    ~TernaryExpression() {
        delete mLhs;
        delete mMhs;
        delete mRhs;
    }

    virtual Type getType(const AST &ast) {
        return coalesceTypes(mMhs->getType(ast), mRhs->getType(ast));
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        return mLhs->toString(atomCase) + " ? " + mMhs->toString(atomCase) + " : " + mRhs->toString(atomCase);
    }

private:
    Expression* mLhs;
    Expression* mMhs;
    Expression* mRhs;

    DISALLOW_COPY_AND_ASSIGN(TernaryExpression);
};

struct ArraySubscript : Expression {
    ArraySubscript(std::string id, Expression* subscript)
    : mId(id), mSubscript(subscript)
    {}
    ~ArraySubscript() {
        delete mSubscript;
    }

    virtual Type getType(const AST &) {
        return Type::UNKNOWN;
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        return mId + "[" + mSubscript->toString(atomCase) + "]";
    }

private:
    std::string mId;
    Expression* mSubscript;

    DISALLOW_COPY_AND_ASSIGN(ArraySubscript);
};

struct FunctionCall : Expression {
    FunctionCall(std::string id, std::vector<Expression *> *args)
    : mId(id), mArgs(args)
    {}
    ~FunctionCall() {
        if(mArgs != NULL) {
            for(auto* args : *mArgs) {
                delete args;
            }
        }
        delete mArgs;
    }

    virtual Type getType(const AST &) {
        return Type::UNKNOWN;
    }
    virtual std::string toString(StringHelper::Case atomCase) {
        std::string out = mId + "(";

        for (auto it = mArgs->begin(); it != mArgs->end(); ++it) {
            if (it != mArgs->begin()) {
                out += ", ";
            }

            out += (*it)->toString(atomCase);
        }

        out += ")";

        return out;
    }

private:
    std::string mId;
    std::vector<Expression *> *mArgs;

    DISALLOW_COPY_AND_ASSIGN(FunctionCall);
};

// static
Expression *Expression::parenthesize(Expression *inner) {
    return new ParenthesizedExpression(inner);
}

// static
Expression *Expression::atom(Type type, const std::string &value, bool isId) {
    return new AtomExpression(type, value, isId);
}

// static
Expression *Expression::unary(std::string op, Expression *rhs) {
    return new UnaryExpression(op, rhs);
}

// static
Expression *Expression::binary(Expression *lhs, std::string op, Expression *rhs) {
    return new BinaryExpression(lhs, op, rhs);
}

// static
Expression *Expression::ternary(Expression *lhs, Expression *mhs, Expression *rhs) {
    return new TernaryExpression(lhs, mhs, rhs);
}

// static
Expression *Expression::arraySubscript(std::string id, Expression *subscript) {
    return new ArraySubscript(id, subscript);
}

// static
Expression *Expression::functionCall(std::string id, std::vector<Expression *> *args) {
    return new FunctionCall(id, args);
}


} //namespace android
