/*
 * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641 8075526 8130914
 *      8161942 8206389
 * @summary Test ZOS and ZIS timestamp in extra field correctly
 */

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.time.Instant;
import java.util.Arrays;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;



public class TestExtraTime {

    public static void main(String[] args) throws Throwable{

        File src = new File(System.getProperty("test.src", "."), "TestExtraTime.java");
        if (!src.exists()) {
            return;
        }

        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");

        // A structurally valid extra data example
        byte[] sampleExtra = new byte[Short.BYTES*3];
        ByteBuffer.wrap(sampleExtra).order(ByteOrder.LITTLE_ENDIAN)
                .putShort((short) 123)         // ID:   123
                .putShort((short) Short.BYTES) // Size: 2
                .putShort((short) 42);         // Data: Two bytes

        for (byte[] extra : new byte[][] { null, sampleExtra}) {

            // ms-dos 1980 epoch problem
            test0(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
            // negative epoch time
            test0(FileTime.from(-100, TimeUnit.DAYS), null, null, null, extra);

            long time = src.lastModified();
            test(FileTime.from(time, TimeUnit.MILLISECONDS),
                 FileTime.from(time + 300000, TimeUnit.MILLISECONDS),
                 FileTime.from(time - 300000, TimeUnit.MILLISECONDS),
                 tz, extra);

            // now
            time = Instant.now().toEpochMilli();
            test(FileTime.from(time, TimeUnit.MILLISECONDS),
                 FileTime.from(time + 300000, TimeUnit.MILLISECONDS),
                 FileTime.from(time - 300000, TimeUnit.MILLISECONDS),
                 tz, extra);

            // unix 2038
            time = 0x80000000L;
            test(FileTime.from(time, TimeUnit.SECONDS),
                 FileTime.from(time, TimeUnit.SECONDS),
                 FileTime.from(time, TimeUnit.SECONDS),
                 tz, extra);

            // mtime < unix 2038
            time = 0x7fffffffL;
            test(FileTime.from(time, TimeUnit.SECONDS),
                 FileTime.from(time + 30000, TimeUnit.SECONDS),
                 FileTime.from(time + 30000, TimeUnit.SECONDS),
                 tz, extra);
        }

        testNullHandling();
        testTagOnlyHandling();
        testTimeConversions();
        testNullMtime();
    }

    static void test(FileTime mtime, FileTime atime, FileTime ctime,
                     TimeZone tz, byte[] extra) throws Throwable {
        test0(mtime, null, null, null, extra);
        test0(mtime, null, null, tz, extra);    // non-default tz
        test0(mtime, atime, null, null, extra);
        test0(mtime, null, ctime, null, extra);
        test0(mtime, atime, ctime, null, extra);
        test0(mtime, atime, null, tz, extra);
        test0(mtime, null, ctime, tz, extra);
        test0(mtime, atime, ctime, tz, extra);
    }

    static void test0(FileTime mtime, FileTime atime, FileTime ctime,
                     TimeZone tz, byte[] extra) throws Throwable {
        System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
                          mtime, atime, ctime);
        TimeZone tz0 = TimeZone.getDefault();
        if (tz != null) {
            TimeZone.setDefault(tz);
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(baos);
        ZipEntry ze = new ZipEntry("TestExtraTime.java");
        ze.setExtra(extra);
        ze.setLastModifiedTime(mtime);
        if (atime != null)
            ze.setLastAccessTime(atime);
        if (ctime != null)
            ze.setCreationTime(ctime);
        zos.putNextEntry(ze);
        zos.write(new byte[] { 1,2 ,3, 4});

        // append an extra entry to help check if the length and data
        // of the extra field are being correctly written (in previous
        // entry).
        if (extra != null) {
            ze = new ZipEntry("TestExtraEntry");
            zos.putNextEntry(ze);
        }
        zos.close();
        if (tz != null) {
            TimeZone.setDefault(tz0);
        }
        // ZipInputStream
        ZipInputStream zis = new ZipInputStream(
                                 new ByteArrayInputStream(baos.toByteArray()));
        ze = zis.getNextEntry();
        zis.close();
        check(mtime, atime, ctime, ze, extra);

        // ZipFile
        Path zpath = Paths.get(System.getProperty("test.dir", "."),
                               "TestExtraTime.zip");
        Path zparent = zpath.getParent();
        if (zparent != null && !Files.isWritable(zparent)) {
            System.err.format("zpath %s parent %s is not writable%n",
                zpath, zparent);
        }
        if (Files.exists(zpath)) {
            System.err.format("zpath %s already exists%n", zpath);
            if (Files.isDirectory(zpath)) {
                System.err.format("%n%s contents:%n", zpath);
                Files.list(zpath).forEach(System.err::println);
            }
            FileOwnerAttributeView foav = Files.getFileAttributeView(zpath,
                FileOwnerAttributeView.class);
            System.err.format("zpath %s owner: %s%n", zpath, foav.getOwner());
            System.err.format("zpath %s permissions:%n", zpath);
            Set<PosixFilePermission> perms =
                Files.getPosixFilePermissions(zpath);
            perms.stream().forEach(System.err::println);
        }
        if (Files.isSymbolicLink(zpath)) {
            System.err.format("zpath %s is a symbolic link%n", zpath);
        }
        Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
        try (ZipFile zf = new ZipFile(zpath.toFile())) {
            ze = zf.getEntry("TestExtraTime.java");
            // ZipFile read entry from cen, which does not have a/ctime,
            // for now.
            check(mtime, null, null, ze, extra);
        } finally {
            Files.delete(zpath);
        }
    }

    static void check(FileTime mtime, FileTime atime, FileTime ctime,
                      ZipEntry ze, byte[] extra) {
        /*
        System.out.printf("    mtime [%tc]: [%tc]/[%tc]%n",
                          mtime.to(TimeUnit.MILLISECONDS),
                          ze.getTime(),
                          ze.getLastModifiedTime().to(TimeUnit.MILLISECONDS));
         */
        if (mtime != null &&
            mtime.to(TimeUnit.SECONDS) !=
            ze.getLastModifiedTime().to(TimeUnit.SECONDS)) {
            throw new RuntimeException("Timestamp: storing mtime failed!");
        }
        if (atime != null &&
            atime.to(TimeUnit.SECONDS) !=
            ze.getLastAccessTime().to(TimeUnit.SECONDS))
            throw new RuntimeException("Timestamp: storing atime failed!");
        if (ctime != null &&
            ctime.to(TimeUnit.SECONDS) !=
            ze.getCreationTime().to(TimeUnit.SECONDS))
            throw new RuntimeException("Timestamp: storing ctime failed!");
        if (extra != null) {
            // if extra data exists, the current implementation put it at
            // the end of the extra data array (implementation detail)
            byte[] extra1 = ze.getExtra();
            if (extra1 == null || extra1.length < extra.length ||
                !Arrays.equals(Arrays.copyOfRange(extra1,
                                                  extra1.length - extra.length,
                                                  extra1.length),
                               extra)) {
                throw new RuntimeException("Timestamp: storing extra field failed!");
            }
        }
    }

    static void testNullHandling() {
        ZipEntry ze = new ZipEntry("TestExtraTime.java");
        try {
            ze.setLastAccessTime(null);
            throw new RuntimeException("setLastAccessTime(null) should throw NPE");
        } catch (NullPointerException ignored) {
            // pass
        }
        try {
            ze.setCreationTime(null);
            throw new RuntimeException("setCreationTime(null) should throw NPE");
        } catch (NullPointerException ignored) {
            // pass
        }
        try {
            ze.setLastModifiedTime(null);
            throw new RuntimeException("setLastModifiedTime(null) should throw NPE");
        } catch (NullPointerException ignored) {
            // pass
        }
    }

    // verify that setting and getting any time is possible as per the intent
    // of 4759491
    static void testTimeConversions() {
        // Sample across the entire range
        long step = Long.MAX_VALUE / 100L;
        testTimeConversions(Long.MIN_VALUE, Long.MAX_VALUE - step, step);

        // Samples through the near future
        long currentTime = System.currentTimeMillis();
        testTimeConversions(currentTime, currentTime + 1_000_000, 10_000);
    }

    static void testTimeConversions(long from, long to, long step) {
        ZipEntry ze = new ZipEntry("TestExtraTime.java");
        for (long time = from; time <= to; time += step) {
            ze.setTime(time);
            FileTime lastModifiedTime = ze.getLastModifiedTime();
            if (lastModifiedTime.toMillis() != time) {
                throw new RuntimeException("setTime should make getLastModifiedTime " +
                        "return the specified instant: " + time +
                        " got: " + lastModifiedTime.toMillis());
            }
            if (ze.getTime() != time) {
                throw new RuntimeException("getTime after setTime, expected: " +
                        time + " got: " + ze.getTime());
            }
        }
    }

    static void check(ZipEntry ze, byte[] extra) {
        if (extra != null) {
            byte[] extra1 = ze.getExtra();
            if (extra1 == null || extra1.length < extra.length ||
                !Arrays.equals(Arrays.copyOfRange(extra1,
                                                  extra1.length - extra.length,
                                                  extra1.length),
                               extra)) {
                throw new RuntimeException("Timestamp: storing extra field failed!");
            }
        }
    }

    static void testTagOnlyHandling() throws Throwable {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] extra = new byte[] { 0x0a, 0, 4, 0, 0, 0, 0, 0 };
        try (ZipOutputStream zos = new ZipOutputStream(baos)) {
            ZipEntry ze = new ZipEntry("TestExtraTime.java");
            ze.setExtra(extra);
            zos.putNextEntry(ze);
            zos.write(new byte[] { 1,2 ,3, 4});
        }
        try (ZipInputStream zis = new ZipInputStream(
                 new ByteArrayInputStream(baos.toByteArray()))) {
            ZipEntry ze = zis.getNextEntry();
            check(ze, extra);
        }
        Path zpath = Paths.get(System.getProperty("test.dir", "."),
                               "TestExtraTime.zip");
        Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
        try (ZipFile zf = new ZipFile(zpath.toFile())) {
            ZipEntry ze = zf.getEntry("TestExtraTime.java");
            check(ze, extra);
        } finally {
            Files.delete(zpath);
        }
    }

    static void checkLastModifiedTimeDOS(FileTime mtime, ZipEntry ze) {
        FileTime lmt = ze.getLastModifiedTime();
        if ((lmt.to(TimeUnit.SECONDS) >>> 1) != (mtime.to(TimeUnit.SECONDS) >>> 1) ||
            lmt.to(TimeUnit.MILLISECONDS) != ze.getTime() ||
            lmt.to(TimeUnit.MILLISECONDS) % 1000 != 0) {
            throw new RuntimeException("Timestamp: storing mtime in dos format failed!");
        }
    }

    static void testNullMtime() throws Throwable {
        Instant now = Instant.now();
        FileTime ctime = FileTime.from(now);
        FileTime atime = FileTime.from(now.plusSeconds(7));
        FileTime mtime = FileTime.from(now.plusSeconds(13));
        System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
                          mtime, atime, ctime);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (ZipOutputStream zos = new ZipOutputStream(baos)) {
            ZipEntry ze = new ZipEntry("TestExtraTime.java");
            ze.setCreationTime(ctime);
            ze.setLastAccessTime(atime);
            // ze.setLastModifiedTime(now);
            ze.setTime(mtime.toMillis());
            zos.putNextEntry(ze);
            zos.write(new byte[] { 1,2 ,3, 4});
        }

        try (ZipInputStream zis = new ZipInputStream(
                 new ByteArrayInputStream(baos.toByteArray()))) {
            ZipEntry ze = zis.getNextEntry();
            // check LOC
            check(null, atime, ctime, ze, null);
            checkLastModifiedTimeDOS(mtime, ze);
        }

        Path zpath = Paths.get(System.getProperty("test.dir", "."),
                               "TestExtraTime.zip");
        Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
        try (ZipFile zf = new ZipFile(zpath.toFile())) {
            ZipEntry ze = zf.getEntry("TestExtraTime.java");
            // check CEN
            checkLastModifiedTimeDOS(mtime, ze);
        } finally {
            Files.delete(zpath);
        }
    }
}
