/*
 * Copyright (c) 2014,2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package test.java.time.temporal;

import static java.time.temporal.ChronoField.DAY_OF_WEEK;
import static org.testng.Assert.assertEquals;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.chrono.ThaiBuddhistDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
import java.time.temporal.WeekFields;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
 * Test.
 */
@Test
public class TestIsoWeekFields {

    @DataProvider(name = "fields")
    Object[][] data_Fields() {
        return new Object[][] {
                {IsoFields.WEEK_OF_WEEK_BASED_YEAR, IsoFields.WEEK_BASED_YEAR},
                {WeekFields.ISO.weekOfWeekBasedYear(), WeekFields.ISO.weekBasedYear()},
        };
    }

    //-----------------------------------------------------------------------
    // WEEK_OF_WEEK_BASED_YEAR
    //-----------------------------------------------------------------------
    @Test(dataProvider = "fields")
    public void test_WOWBY_basics(TemporalField weekField, TemporalField yearField) {
        assertEquals(weekField.isDateBased(), true);
        assertEquals(weekField.isTimeBased(), false);
        assertEquals(weekField.getBaseUnit(), ChronoUnit.WEEKS);
        assertEquals(weekField.getRangeUnit(), IsoFields.WEEK_BASED_YEARS);
    }

    @Test(dataProvider = "fields")
    public void test_WOWBY_isSupportedBy(TemporalField weekField, TemporalField yearField) {
        assertEquals(weekField.isSupportedBy(LocalTime.NOON), false);
        assertEquals(weekField.isSupportedBy(MonthDay.of(2, 1)), false);
        assertEquals(weekField.isSupportedBy(LocalDate.MIN), true);
        assertEquals(weekField.isSupportedBy(OffsetDateTime.MAX), true);
    }

    @Test
    public void test_WOWBY_isSupportedBy_fieldsDiffer() {
        assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
        assertEquals(WeekFields.ISO.weekOfWeekBasedYear().isSupportedBy(ThaiBuddhistDate.now()), true);
    }

    @Test(dataProvider = "fields")
    public void test_WOWBY_range(TemporalField weekField, TemporalField yearField) {
        assertEquals(weekField.range(), ValueRange.of(1, 52, 53));
    }

    @Test(dataProvider = "fields")
    public void test_WOWBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) {
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(1, 52));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 29)), ValueRange.of(1, 52));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 30)), ValueRange.of(1, 52));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 28)), ValueRange.of(1, 52));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 29)), ValueRange.of(1, 53));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 3)), ValueRange.of(1, 53));
        assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 4)), ValueRange.of(1, 52));
    }

    //-----------------------------------------------------------------------
    // WEEK_BASED_YEAR
    //-----------------------------------------------------------------------
    @Test(dataProvider = "fields")
    public void test_WBY_basics(TemporalField weekField, TemporalField yearField) {
        assertEquals(yearField.isDateBased(), true);
        assertEquals(yearField.isTimeBased(), false);
        assertEquals(yearField.getBaseUnit(), IsoFields.WEEK_BASED_YEARS);
        assertEquals(yearField.getRangeUnit(), ChronoUnit.FOREVER);
    }

    @Test(dataProvider = "fields")
    public void test_WBY_isSupportedBy(TemporalField weekField, TemporalField yearField) {
        assertEquals(yearField.isSupportedBy(LocalTime.NOON), false);
        assertEquals(yearField.isSupportedBy(MonthDay.of(2, 1)), false);
        assertEquals(yearField.isSupportedBy(LocalDate.MIN), true);
        assertEquals(yearField.isSupportedBy(OffsetDateTime.MAX), true);
    }

    @Test
    public void test_WBY_isSupportedBy_ISO() {
        assertEquals(IsoFields.WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
    }

    @Test
    public void test_Unit_isSupportedBy_ISO() {
        assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(LocalDate.now()),true);
        assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
        assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(LocalDate.now()),true);
        assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
    }

    @Test(dataProvider = "fields")
    public void test_WBY_range(TemporalField weekField, TemporalField yearField) {
        assertEquals(yearField.range(), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
    }

    @Test(dataProvider = "fields")
    public void test_WBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) {
        assertEquals(yearField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
    }

    //-----------------------------------------------------------------------
    @Test(dataProvider = "fields")
    public void test_getFrom(TemporalField weekField, TemporalField yearField) {
        // tests every day from 2011 to 2016 inclusive
        LocalDate date = LocalDate.of(2011, 1, 3);
        int wby = 2011;
        int week = 1;
        int dow = 1;
        for (int i = 1; i <= ((52 + 52 + 52 + 52 + 53 + 52) * 7); i++) {
            assertEquals(yearField.getFrom(date), wby);
            assertEquals(weekField.getFrom(date), week);
            assertEquals(DAY_OF_WEEK.getFrom(date), dow);
            if (dow == 7) {
                dow = 1;
                week++;
            } else {
                dow++;
            }
            if (week > wbyLen(wby)) {
                week = 1;
                wby++;
            }
            date = date.plusDays(1);
        }
        assertEquals(yearField.getFrom(date), 2017);
        assertEquals(weekField.getFrom(date), 1);
        assertEquals(DAY_OF_WEEK.getFrom(date), 1);
    }

    @Test(dataProvider = "fields")
    public void test_adjustInto_dow(TemporalField weekField, TemporalField yearField) {
        // tests every day from 2012 to 2016 inclusive
        LocalDate date = LocalDate.of(2012, 1, 2);
        int wby = 2012;
        int week = 1;
        int dow = 1;
        for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
            for (int j = 1; j <= 7; j++) {
                LocalDate adjusted = DAY_OF_WEEK.adjustInto(date, j);
                assertEquals(adjusted.get(DAY_OF_WEEK), j);
                assertEquals(adjusted.get(weekField), week);
                assertEquals(adjusted.get(yearField), wby);
            }
            if (dow == 7) {
                dow = 1;
                week++;
            } else {
                dow++;
            }
            if (week > wbyLen(wby)) {
                week = 1;
                wby++;
            }
            date = date.plusDays(1);
        }
    }

    @Test(dataProvider = "fields")
    public void test_adjustInto_week(TemporalField weekField, TemporalField yearField) {
        // tests every day from 2012 to 2016 inclusive
        LocalDate date = LocalDate.of(2012, 1, 2);
        int wby = 2012;
        int week = 1;
        int dow = 1;
        for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
            int weeksInYear = (wby == 2015 ? 53 : 52);
            for (int j = 1; j <= weeksInYear; j++) {
                LocalDate adjusted = weekField.adjustInto(date, j);
                assertEquals(adjusted.get(weekField), j);
                assertEquals(adjusted.get(DAY_OF_WEEK), dow);
                assertEquals(adjusted.get(yearField), wby);
            }
            if (dow == 7) {
                dow = 1;
                week++;
            } else {
                dow++;
            }
            if (week > wbyLen(wby)) {
                week = 1;
                wby++;
            }
            date = date.plusDays(1);
        }
    }

    @Test(dataProvider = "fields")
    public void test_adjustInto_wby(TemporalField weekField, TemporalField yearField) {
        // tests every day from 2012 to 2016 inclusive
        LocalDate date = LocalDate.of(2012, 1, 2);
        int wby = 2012;
        int week = 1;
        int dow = 1;
        for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
            for (int j = 2004; j <= 2015; j++) {
                LocalDate adjusted = yearField.adjustInto(date, j);
                assertEquals(adjusted.get(yearField), j);
                assertEquals(adjusted.get(DAY_OF_WEEK), dow);
                assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(j) == 52 ? 52 : week), "" + date + " " + adjusted);
            }
            if (dow == 7) {
                dow = 1;
                week++;
            } else {
                dow++;
            }
            if (week > wbyLen(wby)) {
                week = 1;
                wby++;
            }
            date = date.plusDays(1);
        }
    }

    @Test(dataProvider = "fields")
    public void test_addTo_weekBasedYears(TemporalField weekField, TemporalField yearField) {
        // tests every day from 2012 to 2016 inclusive
        LocalDate date = LocalDate.of(2012, 1, 2);
        int wby = 2012;
        int week = 1;
        int dow = 1;
        for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
            for (int j = -5; j <= 5; j++) {
                LocalDate adjusted = IsoFields.WEEK_BASED_YEARS.addTo(date, j);
                assertEquals(adjusted.get(yearField), wby + j);
                assertEquals(adjusted.get(DAY_OF_WEEK), dow);
                assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(wby + j) == 52 ? 52 : week), "" + date + " " + adjusted);
            }
            if (dow == 7) {
                dow = 1;
                week++;
            } else {
                dow++;
            }
            if (week > wbyLen(wby)) {
                week = 1;
                wby++;
            }
            date = date.plusDays(1);
        }
    }

    private int wbyLen(int wby) {
        return (wby == 2004 || wby == 2009 || wby == 2015 || wby == 2020 ? 53 : 52);
    }

}
