/*
 *
 * Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.ClobUpdatableReaderTest
 *
 * 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.derbyTesting.functionTests.tests.jdbcapi;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import junit.framework.Test;
import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.BaseTestSuite;
import org.apache.derbyTesting.junit.Decorator;
import org.apache.derbyTesting.junit.TestConfiguration;

/**
 * Test class to test <code>UpdateableReader</code> for <code>Clob</code> in
 * embedded driver.
 */
public class ClobUpdatableReaderTest extends BaseJDBCTestCase {

    private final String dummy = "This is a new String";

    public ClobUpdatableReaderTest (String name) {
        super (name);
    }

    /**
     * Test updating a large clob
     */
    public void testUpdateableStoreReader () throws Exception {
        getConnection().setAutoCommit (false);
        PreparedStatement ps = prepareStatement ("insert into updateClob " +
                "(id , data) values (? ,?)");
        ps.setInt (1, 2);
        StringBuffer sb = new StringBuffer ();
        String base = "SampleSampleSample";
        for (int i = 0; i < 100000; i++) {
            sb.append (base);
        }
        //insert a large enough data to ensure stream is created in dvd
        ps.setCharacterStream (2, new StringReader (sb.toString()),
                                            sb.length());
        ps.execute();
        ps.close();
        Statement stmt = createStatement ();
        ResultSet rs = stmt.executeQuery("select data from " +
                "updateClob where id = 2");
        rs.next();
        Clob clob = rs.getClob (1);
        rs.close();
        stmt.close();
        assertEquals (sb.length(), clob.length());
        Reader r = clob.getCharacterStream();
        String newString = "this is a new string";
        //access reader before modifying the clob
        long l = r.skip (100);
        clob.setString (1001, newString);
        //l chars are already skipped
        long toSkip = 1000 - l;
        while (toSkip > 0) {
            long skipped = r.skip (toSkip);
            toSkip -= skipped;
        }
        char [] newdata = new char [newString.length()];
        int len = r.read(newdata);
        assertEquals ("updated not reflected", newString,
                                new String (newdata, 0, len));
        r.close();
    }

    /**
     * Tests updates on reader.
     */
    public void testUpdateableReader () throws Exception {
        getConnection().setAutoCommit (false);
        PreparedStatement ps = prepareStatement ("insert into updateClob " +
                "(id , data) values (? ,?)");
        ps.setInt (1, 1);
        StringBuffer sb = new StringBuffer ();
        String base = "SampleSampleSample";
        for (int i = 0; i < 100; i++) {
            sb.append (base);
        }
        ps.setCharacterStream (2, new StringReader (sb.toString()),
                                            sb.length());
        ps.execute();
        ps.close();
        Statement stmt = createStatement ();
        ResultSet rs = stmt.executeQuery("select data from " +
                "updateClob where id = 1");
        rs.next();
        Clob clob = rs.getClob (1);
        rs.close();
        stmt.close();
        assertEquals (sb.length(), clob.length());
        Reader r = clob.getCharacterStream();
        char [] clobData = new char [sb.length()];
        r.read (clobData);
        assertEquals ("mismatch from inserted string",
                            String.valueOf (clobData), sb.toString());
        r.close();
        //update before gettting the reader
        clob.setString (50, dummy);
        r = clob.getCharacterStream();
        r.skip (49);
        char [] newChars = new char [dummy.length()];
        r.read (newChars);
        assertEquals ("update not reflected", dummy,
                                    String.valueOf (newChars));
        //update again and see if stream is refreshed
        clob.setString (75, dummy);
        r.skip (75 - 50 - dummy.length());
        char [] testChars = new char [dummy.length()];
        r.read (testChars);
        assertEquals ("update not reflected", dummy,
                                    String.valueOf (newChars));
        r.close();
        //try inserting some unicode string
        String unicodeStr = getUnicodeString();
        clob.setString (50, unicodeStr);
        char [] utf16Chars = new char [unicodeStr.length()];
        r = clob.getCharacterStream();
        r.skip(49);
        r.read(utf16Chars);
        assertEquals ("update not reflected",  unicodeStr,
                                    String.valueOf (utf16Chars));
        r.close();
        Writer w = clob.setCharacterStream (1);
        //write enough data to switch the data to file
        r = clob.getCharacterStream ();
        for (int i = 0; i < 10000; i++) {
            w.write (dummy);
        }
        w.close();
        clob.setString (500, unicodeStr);
        r.skip (499);
        char [] unicodeChars = new char [unicodeStr.length()];
        r.read (unicodeChars);
        assertEquals ("update not reflected",  unicodeStr,
                                    String.valueOf (unicodeChars));
    }

    /**
     * Tests that the Clob can handle multiple streams and the length call
     * multiplexed.
     * <p>
     * This test was written after bug DERBY-2806 was reported, where getting
     * the length of the Clob after fetching a stream from it would exhaust
     * the stream and cause the next read to return -1.
     * <p>
     * The test is written to work on a Clob that operates on streams from
     * the store, which currently means that it must be over a certain size
     * and that no modifying methods can be called on it.
     */
    public void testMultiplexedOperationProblem()
            throws IOException, SQLException {
        getConnection().setAutoCommit(false);
        int length = 266000;
        PreparedStatement ps = prepareStatement(
                "insert into updateClob (id, data) values (?,?)");
        ps.setInt(1, length);
        ps.setCharacterStream(2, new LoopingAlphabetReader(length), length);
        assertEquals(1, ps.executeUpdate());
        ps.close();
        PreparedStatement psFetchClob = prepareStatement(
                "select data from updateClob where id = ?");
        psFetchClob.setInt(1, length);
        ResultSet rs = psFetchClob.executeQuery();
        assertTrue("No Clob of length " + length + " in database", rs.next());
        Clob clob = rs.getClob(1);
        assertEquals(length, clob.length());
        Reader r = clob.getCharacterStream();
        int lastReadChar = r.read();
        lastReadChar = assertCorrectChar(lastReadChar, r.read());
        lastReadChar = assertCorrectChar(lastReadChar, r.read());
        assertEquals(length, clob.length());
        // Must be bigger than internal buffers might be.
        int nextChar;
        for (int i = 2; i < 160000; i++) {
            nextChar = r.read();
            // Check manually to report position where it fails.
            if (nextChar == -1) {
                fail("Failed at position " + i + ", stream should not be" +
                        " exhausted now");
            }
            lastReadChar = assertCorrectChar(lastReadChar, nextChar);
        }
        lastReadChar = assertCorrectChar(lastReadChar, r.read());
        lastReadChar = assertCorrectChar(lastReadChar, r.read());
        InputStream ra = clob.getAsciiStream();
        assertEquals(length, clob.length());
        int lastReadAscii = ra.read();
        lastReadAscii = assertCorrectChar(lastReadAscii, ra.read());
        lastReadAscii = assertCorrectChar(lastReadAscii, ra.read());
        assertEquals(length, clob.length());
        lastReadAscii = assertCorrectChar(lastReadAscii, ra.read());
        lastReadChar = assertCorrectChar(lastReadChar, r.read());
        // Close resources.
        r.close();
        ra.close();
        rs.close();
        psFetchClob.close();
    }


    /**
     * Asserts that the two specified characters follow each other in the
     * modern latin lowercase alphabet.
     */
    private int assertCorrectChar(int prevChar, int nextChar)
            throws IOException {
        assertTrue("Reached EOF unexpectedly", nextChar != -1);
        if (nextChar < 97 && nextChar > 122) {
            fail("Char out of range: " + nextChar);
        }
        if (prevChar < 97 && prevChar > 122) {
            fail("Char out of range: " + prevChar);
        }
        if (prevChar > -1) {
            // Work with modern latin lowercase: 97 - 122
            if (prevChar == 122) {
                assertTrue(prevChar + " -> " + nextChar,
                        nextChar == 97);
            } else {
                assertTrue(prevChar + " -> " + nextChar,
                        nextChar == prevChar +1);
            }
        }
        return nextChar;
    }
    /**
     * Generates a (static) string containing various Unicode characters.
     *
     * @return a string with ASCII and non-ASCII characters
     */
    private String getUnicodeString () {
        char[] fill = new char[4];
        fill[0] = 'd';          // 1 byte UTF8 character (ASCII)
        fill[1] = '\u03a9';     // 2 byte UTF8 character (Greek)
        fill[2] = '\u0e14';     // 3 byte UTF8 character (Thai)
        fill[3] = 'j';          // 1 byte UTF8 character (ASCII)
        StringBuffer sb = new StringBuffer ();
        for (int i = 0; i < 4; i++) {
            sb.append (fill);
        }
        return sb.toString();
    }

    /**
     * Setup the test.
     *
     * @throws SQLException if database access fails
     */
    public void setUp() throws Exception {
        Statement stmt = createStatement ();
        stmt.execute ("create table updateClob " +
                "(id integer primary key, data clob)");
        stmt.close();
        commit();
    }

    public static Test suite() {
        BaseTestSuite ts = new BaseTestSuite("ClobUpdatableReaderTest");
        ts.addTest(TestConfiguration.defaultSuite(
                    ClobUpdatableReaderTest.class));
        BaseTestSuite encSuite =
            new BaseTestSuite("ClobUpdatableReaderTest:encrypted");
        encSuite.addTestSuite (ClobUpdatableReaderTest.class);
        ts.addTest(Decorator.encryptedDatabase (encSuite));
        return ts;
    }

    /**
     * Cleans up the database.
     */
    protected void tearDown() throws java.lang.Exception {
        rollback();
        Statement stmt = createStatement ();
        stmt.execute ("drop table updateClob");
        stmt.close();
        commit();
        super.tearDown();
    }
}
