/*
 * 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.phoenix.end2end;

import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.TypeMismatchException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.sql.*;
import java.util.Properties;

import static org.junit.Assert.*;


public class ToDateFunctionIT extends ParallelStatsDisabledIT {

    private static final long ONE_HOUR_IN_MILLIS = 1000L * 60L * 60L;

    private Connection conn;

    @Before
    public void setUp() throws SQLException {
        conn = DriverManager.getConnection(getUrl());
    }

    @After
    public void tearDown() throws SQLException {
        conn.close();
    }

    private static java.util.Date callToDateFunction(Connection conn, String invocation) throws SQLException {
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(String.format("SELECT %s FROM SYSTEM.CATALOG LIMIT 1", invocation));
        assertTrue(rs.next());
        java.util.Date returnValue = (java.util.Date)rs.getObject(1);
        rs.close();
        stmt.close();
        return returnValue;
    }

    private Date callToDateFunction(String invocation) throws SQLException {
        return (Date)callToDateFunction(conn, invocation);
    }

    private Time callToTimeFunction(String invocation) throws SQLException {
        return (Time)callToDateFunction(conn, invocation);
    }

    private Timestamp callToTimestampFunction(String invocation) throws SQLException {
        return (Timestamp)callToDateFunction(conn, invocation);
    }

    @Test
    public void testToDate_Default() throws SQLException {
        // Default time zone is GMT, so this is timestamp 0
        assertEquals(0L, callToDateFunction("TO_DATE('1970-01-01 00:00:00')").getTime());
        assertEquals(0L, callToDateFunction("TO_DATE('1970-01-01 00:00:00.000')").getTime());
        assertEquals(0L, callToDateFunction("TO_DATE('1970-01-01')").getTime());
        assertEquals(0L, callToDateFunction("TO_DATE('1970/01/01','yyyy/MM/dd')").getTime());

        // Test other ISO 8601 Date Compliant Formats to verify they can be parsed
        try {
            callToDateFunction("TO_DATE('2015-01-27T16:17:57+00:00')");
            callToDateFunction("TO_DATE('2015-01-27T16:17:57Z')");
            callToDateFunction("TO_DATE('2015-W05')");
            callToDateFunction("TO_DATE('2015-W05-2')");
        } catch (Exception ex) {
            fail("TO_DATE Parse ISO8601 Time Failed due to:" + ex);
        }
    }

    @Test
    public void testToTime_Default() throws SQLException {
        // Default time zone is GMT, so this is timestamp 0
        assertEquals(0L, callToTimeFunction("TO_TIME('1970-01-01 00:00:00')").getTime());
        assertEquals(0L, callToTimeFunction("TO_TIME('1970-01-01 00:00:00.000')").getTime());
        assertEquals(0L, callToTimeFunction("TO_TIME('1970-01-01')").getTime());
        assertEquals(0L, callToTimeFunction("TO_TIME('1970/01/01','yyyy/MM/dd')").getTime());

        // Test other ISO 8601 Date Compliant Formats to verify they can be parsed
        try {
            callToTimeFunction("TO_TIME('2015-01-27T16:17:57+00:00')");
            callToTimeFunction("TO_TIME('2015-01-27T16:17:57Z')");
            callToTimeFunction("TO_TIME('2015-W05')");
            callToTimeFunction("TO_TIME('2015-W05-2')");
        } catch (Exception ex) {
            fail("TO_TIME Parse ISO8601 Time Failed due to:" + ex);
        }
    }

    @Test
    public void testToTimestamp_Default() throws SQLException {
        // Default time zone is GMT, so this is timestamp 0
        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970-01-01 00:00:00')").getTime());
        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970-01-01 00:00:00.000')").getTime());
        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970-01-01')").getTime());
        assertEquals(0L, callToTimestampFunction("TO_TIMESTAMP('1970/01/01','yyyy/MM/dd')").getTime());

        // Test other ISO 8601 Date Compliant Formats to verify they can be parsed
        try {
            callToTimestampFunction("TO_TIMESTAMP('2015-01-27T16:17:57+00:00')");
            callToTimestampFunction("TO_TIMESTAMP('2015-01-27T16:17:57Z')");
            callToTimestampFunction("TO_TIMESTAMP('2015-W05')");
            callToTimestampFunction("TO_TIMESTAMP('2015-W05-2')");
        } catch (Exception ex) {
            fail("TO_TIMESTAMP Parse ISO8601 Time Failed due to:" + ex);
        }
    }

    @Test
    public void testToDate_CustomDateFormat() throws SQLException {
        // A date without time component is at midnight
        assertEquals(0L, callToDateFunction("TO_DATE('1970-01-01', 'yyyy-MM-dd')").getTime());
    }

    @Test
    public void testToDate_CustomTimeZone() throws SQLException {
        // We're using GMT+1, so that's an hour before the Java epoch
        assertEquals(
                -ONE_HOUR_IN_MILLIS,
                callToDateFunction("TO_DATE('1970-01-01', 'yyyy-MM-dd', 'GMT+1')").getTime());
    }

    @Test
    public void testToDate_LocalTimeZone() throws SQLException {
        assertEquals(
                Date.valueOf("1970-01-01"),
                callToDateFunction("TO_DATE('1970-01-01', 'yyyy-MM-dd', 'local')"));
    }

    @Test
    public void testToDate_CustomTimeZoneViaQueryServices() throws SQLException {
        Properties props = new Properties();
        props.setProperty(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB, "GMT+1");
        Connection customTimeZoneConn = DriverManager.getConnection(getUrl(), props);

        assertEquals(
                -ONE_HOUR_IN_MILLIS,
                callToDateFunction(customTimeZoneConn, "TO_DATE('1970-01-01 00:00:00.000')").getTime());
    }

    @Test
    public void testToDate_CustomTimeZoneViaQueryServicesAndCustomFormat() throws SQLException {
        Properties props = new Properties();
        props.setProperty(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB, "GMT+1");
        Connection customTimeZoneConn = DriverManager.getConnection(getUrl(), props);

        assertEquals(
                -ONE_HOUR_IN_MILLIS,
                callToDateFunction(
                        customTimeZoneConn, "TO_DATE('1970-01-01', 'yyyy-MM-dd')").getTime());
    }
    
    @Test
    public void testTimestampCast() throws SQLException {
        Properties props = new Properties();
        props.setProperty(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB, "GMT+1");
        Connection customTimeZoneConn = DriverManager.getConnection(getUrl(), props);

        assertEquals(
            1426188807198L,
                callToDateFunction(
                        customTimeZoneConn, "CAST(1426188807198 AS TIMESTAMP)").getTime());
        

        try {
            callToDateFunction(
                    customTimeZoneConn, "CAST(22005 AS TIMESTAMP)");
            fail();
        } catch (TypeMismatchException e) {

        }
    }
    
    @Test
    public void testUnsignedLongToTimestampCast() throws SQLException {
        Properties props = new Properties();
        props.setProperty(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB, "GMT+1");
        Connection conn = DriverManager.getConnection(getUrl(), props);
        conn.setAutoCommit(false);
        try {
            conn.prepareStatement(
                "create table TT("
                        + "a unsigned_int not null, "
                        + "b unsigned_int not null, "
                        + "ts unsigned_long not null "
                        + "constraint PK primary key (a, b, ts))").execute();
            conn.commit();

            conn.prepareStatement("upsert into TT values (0, 22120, 1426188807198)").execute();
            conn.commit();
            
            ResultSet rs = conn.prepareStatement("select a, b, ts, CAST(ts AS TIMESTAMP) from TT").executeQuery();
            assertTrue(rs.next());
            assertEquals(new Date(1426188807198L), rs.getObject(4));
            rs.close();

            try {
                rs = conn.prepareStatement("select a, b, ts, CAST(b AS TIMESTAMP) from TT").executeQuery();
                fail();
            } catch (TypeMismatchException e) {

            }

        } finally {
            conn.close();
        }
    }

    @Test
    public void testVarcharToDateComparision() throws SQLException {
        final String dateString1 = "1900-01-02";
        final String dateString2 = "2100-01-01";

        conn.prepareStatement(
                "CREATE TABLE SB(" +
                        "DATE_STRING VARCHAR(50) NOT NULL " +
                        "CONSTRAINT PK PRIMARY KEY (DATE_STRING))").execute();
        conn.commit();

        String upsertSql = String.format("upsert into SB values (?)");
        PreparedStatement stmt = conn.prepareStatement(upsertSql);
        stmt.setString(1, dateString1);
        stmt.execute();
        stmt.setString(1, dateString2);
        stmt.execute();
        conn.commit();

        String selectSql = "SELECT DATE_STRING FROM SB WHERE TO_DATE(DATE_STRING) > TO_DATE('2001-01-01')";
        ResultSet rs = conn.prepareStatement(selectSql).executeQuery();
        assertTrue(rs.next());
        String obtainedString = rs.getString("DATE_STRING");
        assertEquals("Did not get value that was inserted!!", dateString2, obtainedString);
        assertFalse("No more rows expected!!", rs.next());
    }
    
    @Test
    public void testToDateWithCloneMethod() throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
    	String ddl = "create table " + tableName + " (k varchar primary key, v varchar[])";
        conn.createStatement().execute(ddl);
        String dateStr = "2100-01-01";
        conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('x',ARRAY['"+dateStr+"'])");
        conn.commit();
        ResultSet rs = conn.createStatement().executeQuery("select to_date(v[1], 'yyyy-MM-dd', 'local') from " + tableName);
        
        assertTrue(rs.next());
        assertEquals("Unexpected value for date ", Date.valueOf(dateStr), rs.getDate(1));
        assertFalse(rs.next());
    }
}
