/*
 * 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;
import org.junit.experimental.categories.Category;


@Category(ParallelStatsDisabledTest.class)
public class ModulusExpressionIT extends ParallelStatsDisabledIT {
    
    private static final long SMALL_VALUE = 31L;
    private static final long LARGE_VALUE = 0x5dec6f3847021a9bL;
    
    private static final long[] DIVIDENDS = {Long.MAX_VALUE, LARGE_VALUE, SMALL_VALUE, 0, -SMALL_VALUE, -LARGE_VALUE, Long.MIN_VALUE};
    private static final long[] DIVISORS = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 31, 127, 1024};
    
    private void initTable(Connection conn, long value, String tableName) throws SQLException {

        String ddl = "CREATE TABLE " + tableName + " (pk BIGINT NOT NULL PRIMARY KEY, kv BIGINT)";
        conn.createStatement().execute(ddl);
        String dml = "UPSERT INTO " + tableName + " VALUES(?)";
        PreparedStatement stmt = conn.prepareStatement(dml);
        stmt.setLong(1, value);
        stmt.execute();
        conn.commit();        
    }
    
    private void testDividend(long dividend) throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
        initTable(conn, dividend, tableName);

        for(long divisor : DIVISORS) {
            long remainder = dividend % divisor;
            String sql = "SELECT pk % " + divisor + " FROM " + tableName;
            
            ResultSet rs = conn.createStatement().executeQuery(sql);
            assertTrue(rs.next());
            assertEquals(remainder, rs.getLong(1));
            assertFalse(rs.next());
        }
    }
    
    @Test
    public void testSmallPositiveDividend() throws SQLException {
        testDividend(SMALL_VALUE);
    }
    
    @Test
    public void testLargePositiveDividend() throws SQLException {
        testDividend(LARGE_VALUE);
    }
    
    @Test
    public void testLongMaxDividend() throws SQLException {
        testDividend(Long.MAX_VALUE);
    }      
    
    @Test
    public void testSmallNegativeDividend() throws Exception {
        testDividend(-1 * SMALL_VALUE);
    }
    
    @Test
    public void testLargeNegativeDividend() throws SQLException {
        testDividend(-1 * LARGE_VALUE);
    }
    
    @Test
    public void testLongMinDividend() throws SQLException {
        testDividend(Long.MIN_VALUE);
    }   
    
    @Test
    public void testZeroDividend() throws SQLException {
        testDividend(0);
    }
    
    @Test
    public void testZeroDivisor() throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
        initTable(conn, 0, tableName);
        
        for(long dividend : DIVIDENDS) {
            try {
                String sql = "SELECT " + dividend + " % pk FROM " + tableName;

                // workaround for parser not being able to parse Long.MIN_VALUE
                // see: https://issues.apache.org/jira/browse/PHOENIX-1061
                if(dividend == Long.MIN_VALUE) {
                    sql = "SELECT (" + (dividend + 1) + " + -1) % pk FROM " + tableName;
                }

                ResultSet rs = conn.createStatement().executeQuery(sql);
                rs.next();
                rs.getLong(1);
                fail("modulus by zero: dividend: " + dividend + ". divisor : 0");
            }
            catch (ArithmeticException ex) {
                // success
            }
        }
    }
    
    @Test
    public void testNullDividend() throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
        initTable(conn, SMALL_VALUE, tableName);
        
        for(long divisor : DIVISORS) {
            String sql = "SELECT kv % " + divisor + " FROM " + tableName;
            
            ResultSet rs = conn.createStatement().executeQuery(sql);
            assertTrue(rs.next());
            assertNull(rs.getObject(1));
            assertFalse(rs.next());
        }
    }
    
    @Test
    public void testNullDivisor() throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
        initTable(conn, SMALL_VALUE, tableName);
        
        for(long dividend : DIVIDENDS) {
            String sql = "SELECT " + dividend + " % kv FROM " + tableName;
            
            // workaround for parser not being able to parse Long.MIN_VALUE
            // see: https://issues.apache.org/jira/browse/PHOENIX-1061
            if(dividend == Long.MIN_VALUE) {
                sql = "SELECT (" + (dividend + 1) + " + -1) % kv FROM " + tableName;
            }
            
            ResultSet rs = conn.createStatement().executeQuery(sql);
            assertTrue(rs.next());
            assertNull(rs.getObject(1));
            assertFalse(rs.next());
        }
    }
    
    @Test
    public void testNullEverything() throws SQLException {
        Connection conn = DriverManager.getConnection(getUrl());
        String tableName = generateUniqueName();
        initTable(conn, SMALL_VALUE, tableName);
        
        String sql = "SELECT null % kv FROM " + tableName;
        
        ResultSet rs = conn.createStatement().executeQuery(sql);
        assertTrue(rs.next());
        assertNull(rs.getObject(1));
        assertFalse(rs.next());
        
        sql = "SELECT kv % null FROM " + tableName;
        
        rs = conn.createStatement().executeQuery(sql);
        assertTrue(rs.next());
        assertNull(rs.getObject(1));
        assertFalse(rs.next());
    }


}
