/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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.queplix.core.modules.eql.funcs;

import com.queplix.core.modules.eql.EQLDateObject;
import com.queplix.core.modules.eql.EQLNumberObject;
import com.queplix.core.modules.eql.EQLReqFuncExecutable;
import com.queplix.core.modules.eql.EQLReqOp;
import com.queplix.core.modules.eql.EQLReqSubOpMember;
import com.queplix.core.modules.eql.EQLReqSubOpMemberFunc;
import com.queplix.core.modules.eql.EQLStringObject;
import com.queplix.core.modules.eql.error.EQLException;
import com.queplix.core.modules.eql.error.EQLFunctionParseException;
import com.queplix.core.utils.DateHelper;

import java.util.Calendar;

/**
 * Shift now date
 *
 * @author Sergei Savchuk
 */
public class DateShiftFunc extends EQLReqSubOpMemberFunc
        implements EQLReqFuncExecutable {
    private static final String YEAR = "year";
    private static final String YEAR_SIMPLE = "y";
    private static final String MONTH = "month";
    private static final String MONTH_SIMPLE = "m";
    private static final String DAY = "day";
    private static final String DAY_SIMPLE = "d";

    public EQLReqSubOpMember execute() throws EQLException {
        EQLReqOp firstReqOp = getParameter(0),
                secondReqOp = getParameter(1);
        if(firstReqOp == null || secondReqOp == null) {
            throw new EQLFunctionParseException(this);
        }
        int amount;
        String name;
        // get parameter's values
        try {
            EQLNumberObject firstOptMember = (EQLNumberObject) firstReqOp
                    .getSubOp(0).getMember();
            amount = firstOptMember.getValue().intValue();
            EQLStringObject secOptMember = (EQLStringObject) secondReqOp
                    .getSubOp(0).getMember();
            name = secOptMember.getValue();
        } catch (Exception ex) {
            throw new EQLFunctionParseException(this, ex);
        }
        // shift current date
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateHelper.getNowDate());
        cal.add(defineField(name), amount);
        return new EQLDateObject(cal.getTime());
    }

    private int defineField(String name) {
        name = name.toLowerCase();
        if(name.equals(YEAR_SIMPLE) || name.equals(YEAR)) {
            return Calendar.YEAR;
        } else if(name.equals(MONTH_SIMPLE) || name.equals(MONTH)) {
            return Calendar.MONTH;
        } else if(name.equals(DAY_SIMPLE) || name.equals(DAY)) {
            return Calendar.DAY_OF_YEAR;
        }
        throw new IllegalStateException("Unknown parameter's name: " + name);
    }
}
