package com.neusoft.smart.pos.member.core;

import com.alibaba.fastjson.JSONObject;
import com.neusoft.smart.pos.dto.member.request.CheckMemberLevelRequest;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.member.constants.MemberErrorCode;
import com.neusoft.smart.pos.member.constants.MemberLevelConditionType;

public class AndOrCondition extends MemberLevelCondition {

    private AndOrCondition() {
    }

    private LogicType logic;
    private MemberLevelCondition condition1;
    private MemberLevelCondition condition2;

    @Override
    protected JSONObject getCondition() {
        JSONObject condition = new JSONObject();
        condition.put("logic", logic);
        condition.put("condition1", condition1);
        condition.put("condition2", condition2);
        return condition;
    }

    @Override
    protected MemberLevelConditionType getType() {
        return MemberLevelConditionType.AND_OR_GATE;
    }

    public static MemberLevelCondition.ConditionCreator getConditionCreator() {
        return new AndOrCondition.ConditionCreator();
    }

    @Override
    public boolean isMatch(CheckMemberLevelRequest request) {
        if (logic.getCode() == LogicType.AND.getCode()) {
            return condition1.isMatch(request) && condition2.isMatch(request);
        }
        else if (logic.getCode() == LogicType.OR.getCode()) {
            return condition1.isMatch(request) || condition2.isMatch(request);
        }
        throw new BusinessCommonException(MemberErrorCode.INVALID_DATA);
    }

    private static class ConditionCreator extends MemberLevelCondition.ConditionCreator {

        @Override
        public MemberLevelCondition createInstance(JSONObject para) {
            AndOrCondition rs =  new AndOrCondition();
            rs.logic = LogicType.valueOf(para.getString("logic"));
            rs.condition1 = MemberLevelCondition.createMemberLevelCondition(para.getString("condition1"));
            rs.condition2 = MemberLevelCondition.createMemberLevelCondition(para.getString("condition2"));
            return rs;
        }

        @Override
        public MemberLevelConditionType getMemberLevelConditionType() {
            return MemberLevelConditionType.AND_OR_GATE;
        }

        @Override
        public MemberLevelCondition createDefaultInstance() {
            AndOrCondition result = new AndOrCondition();
            result.logic = LogicType.AND;
            result.condition1 = null;
            result.condition2 = null;
            return result;
        }
    }

    public enum LogicType {

        AND("and", "&"),
        OR("or", "||");

        private String code;

        private String symbol;

        LogicType(String code, String value) {
            this.code = code;
            this.symbol = value;
        }

        public String getCode() {
            return code;
        }

        public String getValue() {
            return symbol;
        }
    }
}
