package org.jenkinsci.plugins.gitclient;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryType;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.UserPrincipal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

class CliGitAPIWindowsFilePermissionsTest {

    private CliGitAPIImpl cliGit;
    private Path file;
    private AclFileAttributeView fileAttributeView;
    private UserPrincipal userPrincipal;

    @TempDir
    private static File tempDir;

    @BeforeEach
    void beforeEach() throws Exception {
        assumeTrue(isWindows());

        cliGit = new CliGitAPIImpl("git", tempDir, null, null);
        file = cliGit.createTempFile("permission", ".suff");
        fileAttributeView = Files.getFileAttributeView(file, AclFileAttributeView.class);
        assertNotNull(fileAttributeView);
        userPrincipal = fileAttributeView.getOwner();
        assertNotNull(userPrincipal);
    }

    @Test
    void test_windows_file_permission_is_set_correctly() throws Exception {
        cliGit.fixSshKeyOnWindows(file);
        assertEquals(1, fileAttributeView.getAcl().size());
        AclEntry aclEntry = fileAttributeView.getAcl().get(0);
        assertTrue(aclEntry.flags().isEmpty());
        assertEquals(CliGitAPIImpl.ACL_ENTRY_PERMISSIONS, aclEntry.permissions());
        assertEquals(userPrincipal, aclEntry.principal());
        assertEquals(AclEntryType.ALLOW, aclEntry.type());
    }

    @Test
    void test_windows_file_permission_are_incorrect() throws Exception {
        // By default files include System and builtin administrators
        assertNotSame(1, fileAttributeView.getAcl().size());
        for (AclEntry entry : fileAttributeView.getAcl()) {
            if (entry.principal().equals(userPrincipal)) {
                assertNotSame(CliGitAPIImpl.ACL_ENTRY_PERMISSIONS, entry.permissions());
            }
        }
    }

    /** inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue */
    private boolean isWindows() {
        return File.pathSeparatorChar == ';';
    }
}
