/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed 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 libcore.java.util.zip;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import libcore.junit.junit3.TestCaseWithRules;
import libcore.junit.util.ResourceLeakageDetector;
import libcore.junit.util.ResourceLeakageDetector.DisableResourceLeakageDetection;
import org.junit.Rule;
import org.junit.rules.TestRule;

public final class ZipOutputStreamTest extends TestCaseWithRules {
    @Rule
    public TestRule guardRule = ResourceLeakageDetector.getRule();

    public void testShortMessage() throws IOException {
        byte[] data = "Hello World".getBytes("UTF-8");
        byte[] zipped = zip("short", data);
        assertEquals(Arrays.toString(data), Arrays.toString(ZipInputStreamTest.unzip("short", zipped)));
    }

    // http://b/3181430 --- a sign-extension bug on CRCs with the top bit set.
    public void test3181430() throws IOException {
        byte[] data = new byte[1]; // CRC32({ 0 }) == 0xd202ef8d
        byte[] zipped = zip("z", data);
        assertEquals(Arrays.toString(data), Arrays.toString(ZipInputStreamTest.unzip("z", zipped)));
    }

    public void testLongMessage() throws IOException {
        byte[] data = new byte[1024 * 1024];
        new Random().nextBytes(data);
        assertTrue(Arrays.equals(data, ZipInputStreamTest.unzip("r", zip("r", data))));
    }

    public static byte[] zip(String name, byte[] bytes) throws IOException {
        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
        ZipOutputStream zippedOut = new ZipOutputStream(bytesOut);

        ZipEntry entry = new ZipEntry(name);
        zippedOut.putNextEntry(entry);
        zippedOut.write(bytes);
        zippedOut.closeEntry();

        zippedOut.close();
        return bytesOut.toByteArray();
    }

    /**
     * Reference implementation does NOT allow writing of an empty zip using a
     * {@link ZipOutputStream}.
     */
    @DisableResourceLeakageDetection(
            why = "InflaterOutputStream.close() does not work properly if finish() throws an"
                    + " exception; finish() throws an exception if the output is invalid.",
            bug = "31797037")
    public void testCreateEmpty() throws IOException {
        File result = File.createTempFile("ZipFileTest", "zip");
        ZipOutputStream out =
                new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
        try {
            out.close();
            fail("Close on empty stream failed to throw exception");
        } catch (ZipException e) {
            // expected
        }
    }

    /** Regression test for null comment causing a NullPointerException during write. */
    public void testNullComment() throws IOException {
        try (ZipOutputStream out = new ZipOutputStream(new ByteArrayOutputStream())) {
            out.setComment(null);
            out.putNextEntry(new ZipEntry("name"));
            out.write(new byte[1]);
            out.closeEntry();
            out.finish();
        }
    }

    /**
     * Test {@link ZipOutputStream#putNextEntry(ZipEntry)} that the current time will be used
     * if the entry has no set modification time.
     */
    public void testPutNextEntryUsingCurrentTime() throws IOException {
        // Zip file truncates time into 1s (before 1980) or 2s precision.
        long timeBeforeZip = System.currentTimeMillis() / 2000 * 2000;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (ZipOutputStream out = new ZipOutputStream(bos)) {
            ZipEntry entryWithoutExplicitTime = new ZipEntry("name");
            // We do not set a time on the entry. We expect ZipOutputStream to use the current
            // system clock value.
            out.putNextEntry(entryWithoutExplicitTime);
            out.closeEntry();
            out.finish();
        }
        // timeAfterZip will normally be rounded down to  1 / 2 seconds boundary as well, but this
        // test accepts either exact or rounded-down values because the rounding behavior is outside
        // of this test's purpose
        long timeAfterZip = System.currentTimeMillis();

        // Read it back, and check the modification time is almost the system clock value
        try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()))) {
            ZipEntry entry = zis.getNextEntry();
            assertEquals("name", entry.getName());
            assertTrue(timeBeforeZip <= entry.getTime());
            assertTrue(timeAfterZip >= entry.getTime());
        }
    }
}
