package org.xbib.files.ftp.test.parser;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.xbib.files.ftp.FTPClientConfig;
import org.xbib.files.ftp.FTPFile;
import java.time.Year;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.xbib.files.ftp.parser.UnixFTPEntryParser;

/**
 * This is a simple TestCase that tests entry parsing using the new FTPClientConfig
 * mechanism. The normal FTPClient cannot handle the different date formats in these
 * entries, however using a configurable format, we can handle it easily.
 * The original system presenting this issue was an AIX system - see bug #27437 for details.
 */
public class FTPConfigEntryParserTest {

    @Test
    public void testParseFieldsOnAIX() {
        // Set a date format for this server type
        FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
        config.setDefaultDateFormatStr("dd MMM HH:mm");
        UnixFTPEntryParser parser = new UnixFTPEntryParser();
        parser.configure(config);
        FTPFile f = parser.parseFTPEntry("-rw-r-----   1 ravensm  sca          814 02 Mar 16:27 ZMIR2.m");
        assertNotNull(f, "Could not parse entry.");
        assertFalse(f.isDirectory(), "Is not a directory.");
        assertTrue(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION), "Should have user read permission.");
        assertTrue(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION), "Should have user write permission.");
        assertFalse(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION), "Should NOT have user execute permission.");
        assertTrue(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION), "Should have group read permission.");
        assertFalse(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION), "Should NOT have group write permission.");
        assertFalse(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION), "Should NOT have group execute permission.");
        assertFalse(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION), "Should NOT have world read permission.");
        assertFalse(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION), "Should NOT have world write permission.");
        assertFalse(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION), "Should NOT have world execute permission.");
        assertEquals(1, f.getHardLinkCount());
        assertEquals("ravensm", f.getUser());
        assertEquals("sca", f.getGroup());
        assertEquals("ZMIR2.m", f.getName());
        assertEquals(814, f.getSize());
        ZonedDateTime zonedDateTime = ZonedDateTime.of(Year.now().getValue(), 3, 2, 16, 27, 0, 0, ZoneId.of("UTC"));
        if (zonedDateTime.isAfter(ZonedDateTime.now())) {
            zonedDateTime = zonedDateTime.minusYears(1);
        }
        assertEquals(zonedDateTime, f.getTimestamp());
    }

    /**
     * This is a new format reported on the mailing lists. Parsing this kind of
     * entry necessitated changing the regex in the parser.
     */
    @Test
    public void testParseEntryWithSymlink() {
        FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
        config.setDefaultDateFormatStr("yyyy-MM-dd HH:mm");
        UnixFTPEntryParser parser = new UnixFTPEntryParser();
        parser.configure(config);
        FTPFile f = parser.parseFTPEntry("lrwxrwxrwx   1 neeme neeme    23 2005-03-02 18:06 macros");
        assertNotNull(f, "Could not parse entry.");
        assertFalse(f.isDirectory(), "Is not a directory.");
        assertTrue(f.isSymbolicLink(), "Is a symbolic link");
        assertTrue(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION), "Should have user read permission.");
        assertTrue(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION), "Should have user write permission.");
        assertTrue(f.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION), "Should have user execute permission.");
        assertTrue(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION), "Should have group read permission.");
        assertTrue(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION), "Should have group write permission.");
        assertTrue(f.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION),"Should have group execute permission.");
        assertTrue(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION), "Should have world read permission.");
        assertTrue(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION), "Should have world write permission.");
        assertTrue(f.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION), "Should have world execute permission.");
        assertEquals(1, f.getHardLinkCount());
        assertEquals("neeme", f.getUser());
        assertEquals("neeme", f.getGroup());
        assertEquals("macros", f.getName());
        assertEquals(23, f.getSize());
        ZonedDateTime zonedDateTime = ZonedDateTime.of(2005, 3, 2, 18, 6, 0, 0, ZoneId.of("UTC"));
        assertEquals(zonedDateTime, f.getTimestamp());
    }
}
