/*
 * Copyright (c) 2019, 2024, 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 8220793
 * @summary Unit test for updating access and modification times of symlinks
 * @requires (os.family == "linux" | os.family == "mac" | os.family == "windows")
 * @library ..
 * @build SymlinkTime
 * @run main/othervm SymlinkTime
 */

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileTime;

public class SymlinkTime {
    public static void main(String[] args) throws IOException {
        Path dir = TestUtil.createTemporaryDirectory();
        if (!TestUtil.supportsSymbolicLinks(dir)) {
            System.out.println("Links not supported: skipping test");
            return;
        }

        try {
            // Create file and symbolic link to it
            final Path file = dir.resolve("file");
            final Path link = dir.resolve("link");
            Files.createFile(file);
            try {
                // Delay creating the link to get different time attributes
                Thread.currentThread().sleep(5000);
            } catch (InterruptedException ignored) {
            }
            Files.createSymbolicLink(link, file);

            // Save file modification and access times
            BasicFileAttributeView view = Files.getFileAttributeView(link,
                BasicFileAttributeView.class);
            BasicFileAttributes attr = view.readAttributes();
            printTimes("Original file times", attr);
            FileTime fileModTime = attr.lastModifiedTime();
            FileTime fileAccTime = attr.lastAccessTime();

            // Read link modification and access times
            view = Files.getFileAttributeView(link,
                BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
            attr = view.readAttributes();
            printTimes("Original link times", attr);

            // Set new base time and offset increment
            long base = 1000000000000L; // 2001-09-09T01:46:40Z
            long delta = 1000*60L;

            // Set new link modification and access times
            FileTime linkModTime = FileTime.fromMillis(base + delta);
            FileTime linkAccTime = FileTime.fromMillis(base + 2L*delta);
            view.setTimes(linkModTime, linkAccTime, null);

            // Verify link modification and access times updated correctly
            view = Files.getFileAttributeView(link,
                BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
            attr = view.readAttributes();
            printTimes("Updated link times", attr);
            check("Link", attr, linkModTime, linkAccTime);

            // Verify file modification and access times unchanged
            view = Files.getFileAttributeView(file,
                BasicFileAttributeView.class);
            attr = view.readAttributes();
            printTimes("File times", attr);
            check("File", attr, fileModTime, fileAccTime);
        } finally {
            TestUtil.removeAll(dir);
        }
    }

    private static void check(String pathType, BasicFileAttributes attr,
        FileTime modTimeExpected, FileTime accTimeExpected) {
        if (!attr.lastModifiedTime().equals(modTimeExpected) ||
            !attr.lastAccessTime().equals(accTimeExpected)) {
            String message = String.format(
                "%s - modification time: expected %s, actual %s;%n" +
                "access time: expected %s, actual %s.%n", pathType,
                modTimeExpected, attr.lastModifiedTime(),
                accTimeExpected, attr.lastAccessTime());
            throw new RuntimeException(message);
        }
    }

    private static void printTimes(String label, BasicFileAttributes attr) {
        System.out.format
            ("%s%ncreation:     %s%nmodification: %s%naccess:       %s%n%n",
            label, attr.creationTime(), attr.lastModifiedTime(),
            attr.lastAccessTime());
    }
}
