/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package com.taobao.weex.el.parse;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Created by furture on 2017/8/28.
 */
public class Operators {


    public static Object dot(Token left, Token right, Object context){
        if(left == null || right == null){
            return null;
        }
        Object leftValue = left.execute(context);
        if(leftValue == null){
            return null;
        }
        Object value =  null;
        if(right.getType() != Token.TYPE_IDENTIFIER){
            Object identifter = right.execute(context);
            if(identifter instanceof Double){
                identifter = ((Double) identifter).intValue();
            }
            String key = identifter == null ? "" : identifter.toString().trim();
            value = Operators.el(leftValue, key);
        }else{
            value = right.execute(leftValue);
        }
        if(value != null){
            return value;
        }
        return  specialKey(leftValue, right.getToken());
    }

    /**
     * get key's value on object
     * */
    public static  Object el(Object context, String key){
        if(context == null){
            return  null;
        }
        // TODO
//        if(context instanceof CellRenderContext){
//            if(WXEnvironment.isApkDebugable()){
//                throw new IllegalArgumentException("rong context CellRenderContext, you should pass it's stack");
//            }
//            context = ((CellRenderContext) context).stack;
//        }
        if(context instanceof ArrayStack){
            ArrayStack stack = (ArrayStack) context;
            for(int index=stack.size()-1; index >= 0; index--){
                Object value = stack.get(index);
                if(value instanceof  Map){
                    Map map = (Map) value;
                    if(map.containsKey(key)){
                        return map.get(key);
                    }
                }
            }
        }
        if(context instanceof Stack){
            Stack stack = (Stack) context;
            for(int index=stack.size()-1; index >= 0; index--){
                Object value = stack.get(index);
                if(value instanceof  Map){
                    Map map = (Map) value;
                    if(map.containsKey(key)){
                        return map.get(key);
                    }
                }
            }
        }

        if(context instanceof  Map){
            return ((Map) context).get(key);
        }

        if(context instanceof List){
            List list = (List) context;
            try{
                return list.get(Integer.parseInt(key));
            }catch (Exception e){}
        }
        if(context.getClass().isArray()){
            try{
                return Array.get(context, Integer.parseInt(key));
            }catch (Exception e){}
        }
        return  null;
    }

    public static  Object specialKey(Object leftValue, String key){
        if("length".equals(key)){
            if(leftValue instanceof  CharSequence){
                return ((CharSequence) leftValue).length();
            }
            if(leftValue instanceof  Map){
                return  ((Map) leftValue).size();
            }
            if(leftValue instanceof  Map){
                return  ((Map) leftValue).size();
            }
            if(leftValue instanceof  List){
                return  ((List) leftValue).size();
            }
            if(leftValue.getClass().isArray()){
                return Array.getLength(leftValue);
            }
        }
        return null;
    }

    public static Object plus(Token left, Token right, Object context){
        Object leftValue = null;
        Object rightValue = null;
        if(left != null){
            leftValue = left.execute(context);
        }
        if(right  != null){
            rightValue = right.execute(context);
        }
        if(leftValue instanceof  CharSequence || rightValue instanceof  CharSequence){
            if(leftValue == null){
                return  rightValue;
            }
            return leftValue.toString() + (rightValue == null ? "" : rightValue.toString());
        }
        if(leftValue instanceof  Number || rightValue instanceof Number){
            return getNumber(leftValue) + getNumber(rightValue);
        }
        if(leftValue == null && rightValue == null){
            return  null;
        }
        if(leftValue == null){
            return  rightValue.toString();
        }
        return leftValue.toString() + (rightValue == null ? "" : rightValue.toString());
    }


    public static Object sub(Token left, Token right, Object context){
        Object leftValue = null;
        Object rightValue = null;
        if(left != null){
            leftValue = left.execute(context);
        }
        if(right  != null){
            rightValue = right.execute(context);
        }
        return getNumber(leftValue) - getNumber(rightValue);
    }

    public static Object div(Token left, Token right, Object context){
        Object leftValue = null;
        Object rightValue = null;
        if(left != null){
            leftValue = left.execute(context);
        }
        if(right  != null){
            rightValue = right.execute(context);
        }
        return getNumber(leftValue)/getNumber(rightValue);
    }

    public static Object mul(Token left, Token right, Object context){
        Object leftValue = null;
        Object rightValue = null;
        if(left != null){
            leftValue = left.execute(context);
        }
        if(right  != null){
            rightValue = right.execute(context);
        }
        return getNumber(leftValue)*getNumber(rightValue);
    }

    public static Object mod(Token left, Token right, Object context){
        Object leftValue = null;
        Object rightValue = null;
        if(left != null){
            leftValue = left.execute(context);
        }
        if(right  != null){
            rightValue = right.execute(context);
        }
        return (getNumber(leftValue))%(getNumber(rightValue));
    }

    /**
     * condition expression
     * */
    public static Object condition(Token selfs, Token first, Token second, Object context){
        boolean value = false;
        if(selfs != null){
            value = isTrue(selfs.execute(context));
        }
        if(value){
            if(first != null){
                return  first.execute(context);
            }
        }else{
            if(second != null){
                return  second.execute(context);
            }
        }
        return null;
    }


    /**
     * is token value is true
     * */
    public static boolean tokenTrue(Token selfs, Object context) {
        if(selfs == null){
            return false;
        }
        Object value = selfs.execute(context);
        return  isTrue(value);
    }

    /**
     * get token number
     * */
    public static double tokenNumber(Token self,  Object context) {
        if(self == null){
            return  0;
        }
        Object value = self.execute(context);
        return  getNumber(value);
    }



    /**
     * isEquls operation
     * */
    public static boolean isEquals(Token left, Token right, Object context){
        if(left == null && right == null){
            return  true;
        }
        Object leftValue =  null;
        if(left != null){
            leftValue  = left.execute(context);
        }
        Object rightValue = null;
        if(right != null) {
            rightValue = right.execute(context);
        }
        if(leftValue == null){
            if(rightValue == null){
                return  true;
            }
            if(rightValue instanceof  CharSequence){
                if(isEmpty(rightValue.toString())){
                    return  true;
                }
            }
            return  false;
        }
        if(rightValue == null){
            if(isEmpty(leftValue.toString())){
                return  true;
            }
            return  false;
        }
        if(leftValue instanceof  Number){
            if(rightValue instanceof  Number){
                return  ((Number) leftValue).doubleValue() == ((Number) rightValue).doubleValue();
            }
            return ((Number) leftValue).doubleValue() == getNumber(rightValue);
        }
        if(rightValue instanceof  Number){
            return getNumber(leftValue) == ((Number) rightValue).doubleValue();
        }
        if(leftValue instanceof CharSequence
                ||  rightValue instanceof CharSequence){
            return  leftValue.toString().trim().equals(rightValue.toString().trim());
        }
        return  leftValue.equals(rightValue);
    }


    /**
     * check whether value is true
     * */
    public static boolean isTrue(Object value){
        if(value == null){
            return  false;
        }
        if(value instanceof  Number){
            return ((Number) value).doubleValue() != 0;
        }
        String bool = value.toString().trim();
        if("false".equals(bool)
                || "undefined".equals(bool)
                || "null".equals(bool)){
            return  false;
        }
        if(isEmpty(bool)){
            return  false;
        }
        return  true;
    }

    /**
     * check String value is empty
     * */
    public static boolean isEmpty(String value){
        if (value == null){
            return  true;
        }
        for(int i=0; i<value.length(); i++){
            if(value.charAt(i) != ' '){
                return  false;
            }
        }
        return true;
    }


    /**
     * get number
     * */
    public static double getNumber(Object value){
        if(value == null){
            return  0;
        }
        if(value instanceof  Number){
            return  ((Number) value).doubleValue();
        }
        try{
            return Double.parseDouble(value.toString());
        }catch (Exception e){return  0;}
    }

    public static boolean isOpEnd(String op){
        return isOpEnd(op.charAt(0));
    }
    /**
     * op end, has none operation, should not enter operator stack.
     * */
    public static boolean isOpEnd(char op){
        if(op == BRACKET_END
                || op == ARRAY_END
                || op == SPACE
                || op == ARRAY_SEPRATOR){
            return true;
        }
        return  false;
    }

    /**
     * is not
     * */
    public static boolean isDot(String opStr){
        char op = opStr.charAt(0);
        return  op == DOT || op == ARRAY_START;
    }




    public static final char BRACKET_END = ')';
    public static final String BRACKET_END_STR = ")";
    public static final char BRACKET_START = '(';
    public static final String BRACKET_START_STR = "(";
    public static final char QUOTE = '"';
    public static final char SINGLE_QUOTE = '\'';
    public static final char DOT = '.';
    public static final String DOT_STR = ".";
    public static final char ARRAY_START = '[';
    public static final String ARRAY_START_STR = "[";
    public static final char ARRAY_SEPRATOR = ',';
    public static final String ARRAY_SEPRATOR_STR = ",";
    public static final char ARRAY_END = ']';
    public static final String ARRAY_END_STR = "]";
    public static final String SPACE_STR = " ";
    public static final char SPACE = ' ';
    public static final char BLOCK_START = '{';
    public static final String BLOCK_START_STR = "{";
    public static final char BLOCK_END = '}';
    public static final String BLOCK_END_STR = "}";
    public static final char DOLLAR = '$';
    public static final String DOLLAR_STR = "$";

    /**
     * condition
     * */
    public static final char  CONDITION_IF = '?';
    public static final String  CONDITION_IF_STRING = "?";
    public static final char  CONDITION_IF_MIDDLE = ':';



    /**
     * match
     * */
    public static final String PLUS ="+";
    public static final String SUB = "-";
    public static final String MUL = "*";
    public static final String DIV = "/";
    public static final String MOD = "%";



    public static final String AND  = "&&";
    public static final String OR  = "||";
    /**
     * and operator
     * */
    public static final String EQUAL = "===";
    public static final String EQUAL2 = "==";
    public static final String NOT_EQUAL = "!==";
    public static final String NOT_EQUAL2 = "!=";
    public static final String AND_NOT = "!";


    public static final String G = ">";
    public static final String GE = ">=";
    public static final String LE = "<=";
    public static final String L = "<";





    /**
     * https://github.com/jquery/esprima/blob/master/src/parser.ts
     * */
    public static Map<String, Integer> OPERATORS_PRIORITY = new HashMap<>();
    static {
        OPERATORS_PRIORITY.put(BLOCK_END_STR, 0);
        OPERATORS_PRIORITY.put(BRACKET_END_STR, 0);
        OPERATORS_PRIORITY.put(SPACE_STR, 0);
        OPERATORS_PRIORITY.put(ARRAY_SEPRATOR_STR, 0);
        OPERATORS_PRIORITY.put(ARRAY_END_STR, 0);


        OPERATORS_PRIORITY.put(OR, 1);
        OPERATORS_PRIORITY.put(AND, 1);

        OPERATORS_PRIORITY.put(EQUAL, 2);
        OPERATORS_PRIORITY.put(EQUAL2, 2);
        OPERATORS_PRIORITY.put(NOT_EQUAL, 2);
        OPERATORS_PRIORITY.put(NOT_EQUAL2, 2);

        OPERATORS_PRIORITY.put(G, 7);
        OPERATORS_PRIORITY.put(GE, 7);
        OPERATORS_PRIORITY.put(L, 7);
        OPERATORS_PRIORITY.put(LE, 8);

        OPERATORS_PRIORITY.put(PLUS, 9);
        OPERATORS_PRIORITY.put(SUB, 9);
        OPERATORS_PRIORITY.put(MUL, 10);
        OPERATORS_PRIORITY.put(DIV, 10);
        OPERATORS_PRIORITY.put(MOD, 10);
        OPERATORS_PRIORITY.put(AND_NOT, 11);

        OPERATORS_PRIORITY.put(DOT_STR, 15);
        
        OPERATORS_PRIORITY.put(ARRAY_START_STR, 16);


        OPERATORS_PRIORITY.put(BRACKET_START_STR, 17);
        OPERATORS_PRIORITY.put(BLOCK_START_STR, 17);


    }


    public static final Map<String,Object> KEYWORDS = new HashMap<>();
    static {
        KEYWORDS.put("null", null);
        KEYWORDS.put("true", Boolean.TRUE);
        KEYWORDS.put("false", Boolean.FALSE);
        KEYWORDS.put("undefined", null);
    }

}
