/*
 *  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.harmony.testframework;

import junit.framework.TestCase;
import junit.framework.TestSuite;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Tests behaviour common to wrapping and filtering implementations of {@link
 * OutputStream}.
 */
public abstract class WrapperTester {

    private boolean throwsExceptions = true;

    /**
     * Creates a new output stream that receives one stream of bytes, optionally
     * transforms it, and emits another stream of bytes to {@code delegate}.
     */
    public abstract OutputStream create(OutputStream delegate) throws Exception;

    /**
     * Decodes the bytes received by the delegate into their original form: the
     * bytes originally received by this wrapper.
     */
    public abstract byte[] decode(byte[] delegateBytes) throws Exception;

    /**
     * Configures whether the stream is expected to throw exceptions when an
     * error is encountered. Classes like {@code PrintStream} report errors via
     * an API method instead.
     */
    public WrapperTester setThrowsExceptions(boolean throwsExceptions) {
        this.throwsExceptions = throwsExceptions;
        return this;
    }

    public final TestSuite createTests() {
        TestSuite result = new TestSuite();
        result.addTest(new WrapperSinkTester()
                .setThrowsExceptions(throwsExceptions)
                .createTests());

        if (throwsExceptions) {
            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
            result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
        } else {
            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
            result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
        }

        return result;
    }

    @Override public String toString() {
        return getClass().getName();
    }

    private class WrapperSinkTester extends SinkTester {
        private ClosableByteArrayOutputStream delegate;

        @Override public OutputStream create() throws Exception {
            delegate = new ClosableByteArrayOutputStream();
            return WrapperTester.this.create(delegate);
        }

        @Override public byte[] getBytes() throws Exception {
            return WrapperTester.this.decode(delegate.bytesOut.toByteArray());
        }

        @Override public String toString() {
            return WrapperTester.this.toString();
        }
    }

    public class WrapperTestCase extends TestCase {

        private WrapperTestCase(String name) {
            super(name);
        }

        @Override public String getName() {
            return WrapperTester.this.toString() + ":" + super.getName();
        }

        public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
            OutputStream o = create(delegate);
            o.write(new byte[] { 8, 6, 7, 5 });
            o.write(new byte[] { 3, 0, 9 });
            o.flush();
            assertTrue(delegate.flushed);
        }

        public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
            OutputStream o = create(delegate);
            o.write(new byte[] { 8, 6, 7, 5 });
            o.write(new byte[] { 3, 0, 9 });
            o.close();
            assertTrue(delegate.flushed);
        }

        public void wrapperTestFlushThrowsViaFlush() throws Exception {
            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();

            OutputStream o = create(delegate);
            try {
                // any of these is permitted to flush
                o.write(new byte[] { 8, 6, 7, 5 });
                o.write(new byte[] { 3, 0, 9 });
                o.flush();
                assertTrue(delegate.flushed);
                fail("flush exception ignored");
            } catch (IOException expected) {
                assertEquals("Flush failed" , expected.getMessage());
            }
        }

        public void wrapperTestFlushThrowsViaClose() throws Exception {
            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();

            OutputStream o = create(delegate);
            try {
                // any of these is permitted to flush
                o.write(new byte[] { 8, 6, 7, 5 });
                o.write(new byte[] { 3, 0, 9 });
                o.close();
                assertTrue(delegate.flushed);
                fail("flush exception ignored");
            } catch (IOException expected) {
                assertEquals("Flush failed" , expected.getMessage());
            }

            try {
                o.write(new byte[] { 4, 4, 5 });
                fail("expected already closed exception");
            } catch (IOException expected) {
            }
        }

        public void wrapperTestCloseThrows() throws Exception {
            FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
            OutputStream o = create(delegate);
            try {
                o.close();
                assertTrue(delegate.closed);
                fail("close exception ignored");
            } catch (IOException expected) {
                assertEquals("Close failed" , expected.getMessage());
            }
        }

        public void wrapperTestCloseThrowsSuppressed() throws Exception {
            FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
            OutputStream o = create(delegate);
            o.close();
            assertTrue(delegate.closed);
        }

        // adding a new test? Don't forget to update createTests().
    }

    private static class ClosableByteArrayOutputStream extends OutputStream {
        private final ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
        private boolean closed = false;

        @Override public void close() throws IOException {
            closed = true;
        }

        @Override public void write(int oneByte) throws IOException {
            if (closed) {
                throw new IOException();
            }
            bytesOut.write(oneByte);
        }
    }

    private static class FailOnFlushOutputStream extends OutputStream {
        boolean flushed = false;
        boolean closed = false;

        @Override public void write(int oneByte) throws IOException {
            if (closed) {
                throw new IOException("Already closed");
            }
        }

        @Override public void close() throws IOException {
            closed = true;
            flush();
        }

        @Override public void flush() throws IOException {
            if (!flushed) {
                flushed = true;
                throw new IOException("Flush failed");
            }
        }
    }

    private static class FailOnCloseOutputStream extends ByteArrayOutputStream {
        boolean closed = false;

        @Override public void close() throws IOException {
            closed = true;
            throw new IOException("Close failed");
        }
    }
}
