/* ====================================================================
   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 org.apache.poi.ss.formula.functions;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.util.LocaleUtil;
import org.junit.jupiter.api.Test;

final class TestDays360 {

    /**
     * @param month 1-based
     */
    private static Date makeDate(int year, int month, int day) {
        Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day);
        return cal.getTime();
    }

    private static Date decrementDay(Date d) {
        Calendar c = LocaleUtil.getLocaleCalendar();
        c.setTime(d);
        c.add(Calendar.DAY_OF_MONTH, -1);
        return c.getTime();
    }

    @Test
    void testBasic() {
        confirm(120, 2009, 1, 15, 2009, 5, 15);
        confirm(158, 2009, 1, 26, 2009, 7, 4);

        // same results in leap years
        confirm(120, 2008, 1, 15, 2008, 5, 15);
        confirm(158, 2008, 1, 26, 2008, 7, 4);

        // longer time spans
        confirm(562, 2008, 8, 11, 2010, 3, 3);
        confirm(916, 2007, 2, 23, 2009, 9, 9);

        // other tests
        confirm(1, makeDate(1993, 2, 28), makeDate(1993, 3, 1), false);
        confirm(1, makeDate(1996, 2, 29), makeDate(1996, 3, 1), false);
        confirm(-2, makeDate(1993, 2, 28), makeDate(1993, 2, 28), false);
        confirm(3, makeDate(1993, 2, 28), makeDate(1993, 3, 1), true);
        confirm(2, makeDate(1996, 2, 29), makeDate(1996, 3, 1), true);

        // from https://support.office.com/en-us/article/DAYS360-function-B9A509FD-49EF-407E-94DF-0CBDA5718C2A
        confirm(1, makeDate(2011, 1, 30), makeDate(2011, 2, 1), false);
        confirm(360, makeDate(2011, 1, 1), makeDate(2011, 12, 31), false);
        confirm(30, makeDate(2011, 1, 1), makeDate(2011, 2, 1), false);
    }

    private static void confirm(int expResult, int y1, int m1, int d1, int y2, int m2, int d2) {
        confirm(expResult, makeDate(y1, m1, d1), makeDate(y2, m2, d2), false);
        confirm(-expResult, makeDate(y2, m2, d2), makeDate(y1, m1, d1), false);
    }

    /**
     * The <tt>method</tt> parameter only makes a difference when the second parameter
     * is the last day of the month that does <em>not</em> have 30 days.
     */
    @Test
    void testMonthBoundaries() {
        // jan
        confirmMonthBoundary(false, 2001, 1, 0, 0, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 1, 0, 0, 1, 2, 3);
        // feb
        confirmMonthBoundary(false, 2001, 2,-2, 1, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 2, 0, 1, 2, 3, 4);
        // mar
        confirmMonthBoundary(false, 2001, 3, 0, 0, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 3, 0, 0, 1, 2, 3);
        // apr
        confirmMonthBoundary(false, 2001, 4, 0, 1, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 4, 0, 1, 2, 3, 4);
        // may
        confirmMonthBoundary(false, 2001, 5, 0, 0, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 5, 0, 0, 1, 2, 3);
        // jun
        confirmMonthBoundary(false, 2001, 6, 0, 1, 2, 3, 4);
        confirmMonthBoundary(true,  2001, 6, 0, 1, 2, 3, 4);
        // leap year
        confirmMonthBoundary(false, 2012, 2, -1, 1, 2, 3, 4);
        confirmMonthBoundary(true,  2012, 2, 0, 1, 2, 3, 4);

        // bug 60029
        Date start = makeDate(2018, 2, 28);
        Date end = makeDate(2018, 3, 31);
        confirm(30, start, end, false);

        // examples from https://support.office.com/en-us/article/DAYS360-function-B9A509FD-49EF-407E-94DF-0CBDA5718C2A
        start = makeDate(2011, 1, 30);
        end = makeDate(2011, 2, 1);
        confirm(1, start, end, false);

        start = makeDate(2011, 1, 1);
        end = makeDate(2011, 12, 31);
        confirm(360, start, end, false);

        start = makeDate(2011, 1, 1);
        end = makeDate(2011, 2, 1);
        confirm(30, start, end, false);
    }


    /**
     * @param monthNo 1-based
     */
    private static void confirmMonthBoundary(boolean method, int year, int monthNo, int...diffs) {
        Date firstDayOfNextMonth = makeDate(year, monthNo+1, 1);
        Date secondArg = decrementDay(firstDayOfNextMonth);
        Date firstArg = secondArg;

        for (int expResult : diffs) {
            confirm(expResult, firstArg, secondArg, method);
            firstArg = decrementDay(firstArg);
        }

    }
    private static void confirm(int expResult, Date firstArg, Date secondArg, boolean method) {
        ValueEval ve;
        if (method) {
            ve = invokeDays360(convert(firstArg), convert(secondArg), BoolEval.TRUE);
        } else {
            ve = invokeDays360(convert(firstArg), convert(secondArg));
        }
        assertTrue(ve instanceof NumberEval, "wrong return type (" + ve.getClass().getName() + ")");

        NumberEval numberEval = (NumberEval) ve;
        String err = String.format(Locale.ROOT, "days360(%tF,%tF,%b) wrong result", firstArg, secondArg, method);
        assertEquals(expResult, numberEval.getNumberValue(), 0, err);
    }

    private static ValueEval invokeDays360(ValueEval...args) {
        return new Days360().evaluate(args, -1, -1);
    }

    private static NumberEval convert(Date d) {
        return new NumberEval(DateUtil.getExcelDate(d));
    }
}
