/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.commons.net.ftp.parser;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileEntryParser;
import org.apache.commons.net.ftp.FTPListParseEngine;

/**
 * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
 * @author <a href="sestegra@free.fr">Stephane ESTE-GRACIAS</a>
 * @version $Id: VMSFTPEntryParserTest.java 657169 2008-05-16 19:07:02Z sebb $
 */
public class VMSFTPEntryParserTest extends FTPParseTestFramework
{
    private static final String[] badsamples =
    {

        "1-JUN.LIS;2              9/9           JUN-2-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
        "1-JUN.LIS;2              a/9           2-JUN-98 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
        "DATA.DIR; 1              1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (,RWED,RWED,RE)",
        "120196.TXT;1           118/126        14-APR-1997 12:45:27 PM  [GROUP,OWNER]    (RWED,,RWED,RE)",
        "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP-1,OWNER]    (RWED,RWED,RWED,RE)",
        "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED2,RWED,RWED,RE)",
        "AA.;2                  152/153        13-FED-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
        "Directory USER1:[TEMP]\r\n\r\n",
        "\r\nTotal 14 files"
    };

    private static final String[] goodsamples =
    {
        "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
        "1-JUN.LIS;3              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
        "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)",
        "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [TRANSLATED]     (,RWED,RWED,RE)",
        "120196.TXT;1           118/126        14-APR-1997 12:45:27  [GROUP,OWNER]    (RWED,,RWED,RE)",
        "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
        "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
        "AA.;2                  152/153        13-FEB-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
        "UCX$REXECD_STARTUP.LOG;1098\r\n                         4/15         24-FEB-2003 13:17:24  [POSTWARE,LP]    (RWED,RWED,RE,)",
        "UNARCHIVE.COM;1          2/15          7-JUL-1997 16:37:45  [POSTWARE,LP]    (RWE,RWE,RWE,RE)",
        "UNXMERGE.COM;15          1/15         20-AUG-1996 13:59:50  [POSTWARE,LP]    (RWE,RWE,RWE,RE)",
        "UNXTEMP.COM;7            1/15         15-AUG-1996 14:10:38  [POSTWARE,LP]    (RWE,RWE,RWE,RE)",
        "UNZIP_AND_ATTACH_FILES.COM;12\r\n                        14/15         24-JUL-2002 14:35:40  [TRANSLATED]    (RWE,RWE,RWE,RE)",
        "UNZIP_AND_ATTACH_FILES.SAV;1\r\n                        14/15         17-JAN-2002 11:13:53  [POSTWARE,LP]    (RWE,RWED,RWE,RE)",
        "FREEWARE40.DIR;1        27/36         16-FEB-1999 10:01:46  [AP_HTTPD,APACHE$WWW                               (RWE,RWE,RE,RE)",
        "1-JUN.LIS;1              9/9           2-jun-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
    };

    private static final String fullListing = "Directory USER1:[TEMP]\r\n\r\n"+
    "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)\r\n"+
    "2-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)\r\n"+
    "3-JUN.LIS;1              9/9           3-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)\r\n"+
    "3-JUN.LIS;4              9/9           7-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)\r\n"+
    "3-JUN.LIS;2              9/9           4-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)\r\n"+
    "3-JUN.LIS;3              9/9           6-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)\r\n"+
    "\r\nTotal 6 files";

    /**
     * @see junit.framework.TestCase#TestCase(String)
     */
    public VMSFTPEntryParserTest(String name)
    {
        super(name);
    }

    /**
     * Test the parsing of the whole list.
     * @throws IOException
     */
    public void testWholeListParse() throws IOException
    {
        VMSFTPEntryParser parser = new VMSFTPEntryParser();
        parser.configure(null);
        FTPListParseEngine engine = new FTPListParseEngine(parser);
        engine.readServerList(
                new ByteArrayInputStream(fullListing.getBytes()), null); // use default encoding
        FTPFile[] files = engine.getFiles();
        assertEquals(6, files.length);
        assertFileInListing(files, "2-JUN.LIS");
        assertFileInListing(files, "3-JUN.LIS");
        assertFileInListing(files, "1-JUN.LIS");
        assertFileNotInListing(files, "1-JUN.LIS;1");

    }

    /**
     * Test the parsing of the whole list.
     * @throws IOException
     */
    public void testWholeListParseWithVersioning() throws IOException
    {

        VMSFTPEntryParser parser = new VMSVersioningFTPEntryParser();
        parser.configure(null);
        FTPListParseEngine engine = new FTPListParseEngine(parser);
        engine.readServerList(
                new ByteArrayInputStream(fullListing.getBytes()), null); // use default encoding
        FTPFile[] files = engine.getFiles();
        assertEquals(3, files.length);
        assertFileInListing(files, "1-JUN.LIS;1");
        assertFileInListing(files, "2-JUN.LIS;1");
        assertFileInListing(files, "3-JUN.LIS;4");
        assertFileNotInListing(files, "3-JUN.LIS;1");
        assertFileNotInListing(files, "3-JUN.LIS");

    }

    public void assertFileInListing(FTPFile[] listing, String name) {
        for (int i = 0; i < listing.length; i++) {
            if (name.equals(listing[i].getName())) {
                return;
            }
        }
        fail("File " + name + " not found in supplied listing");
    }
    public void assertFileNotInListing(FTPFile[] listing, String name) {
        for (int i = 0; i < listing.length; i++) {
            if (name.equals(listing[i].getName())) {
                fail("Unexpected File " + name + " found in supplied listing");
            }
        }
    }

    /**
     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
     */
    @Override
    public void testParseFieldsOnDirectory() throws Exception
    {

        FTPFile dir = getParser().parseFTPEntry("DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)");
        assertTrue("Should be a directory.",
                   dir.isDirectory());
        assertEquals("DATA.DIR",
                     dir.getName());
        assertEquals(512,
                     dir.getSize());
        assertEquals("Tue Jun 02 07:32:04 1998",
                     df.format(dir.getTimestamp().getTime()));
        assertEquals("GROUP",
                     dir.getGroup());
        assertEquals("OWNER",
                     dir.getUser());
        checkPermisions(dir, 0775);


        dir = getParser().parseFTPEntry("DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [TRANSLATED]    (RWED,RWED,,RE)");
        assertTrue("Should be a directory.",
                           dir.isDirectory());
        assertEquals("DATA.DIR",
                             dir.getName());
        assertEquals(512,
                             dir.getSize());
        assertEquals("Tue Jun 02 07:32:04 1998",
                             df.format(dir.getTimestamp().getTime()));
        assertEquals(null,
                     dir.getGroup());
        assertEquals("TRANSLATED",
                     dir.getUser());
        checkPermisions(dir, 0705);
    }

    /**
     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
     */
    @Override
    public void testParseFieldsOnFile() throws Exception
    {
        FTPFile file = getParser().parseFTPEntry("1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RW,R)");
        assertTrue("Should be a file.",
                   file.isFile());
        assertEquals("1-JUN.LIS",
                     file.getName());
        assertEquals(9 * 512,
                     file.getSize());
        assertEquals("Tue Jun 02 07:32:04 1998",
                     df.format(file.getTimestamp().getTime()));
        assertEquals("GROUP",
                     file.getGroup());
        assertEquals("OWNER",
                     file.getUser());
        checkPermisions(file, 0764);


        file = getParser().parseFTPEntry("1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [TRANSLATED]    (RWED,RD,,)");
        assertTrue("Should be a file.",
                   file.isFile());
        assertEquals("1-JUN.LIS",
                     file.getName());
        assertEquals(9 * 512,
                     file.getSize());
        assertEquals("Tue Jun 02 07:32:04 1998",
                     df.format(file.getTimestamp().getTime()));
        assertEquals(null,
                     file.getGroup());
        assertEquals("TRANSLATED",
                     file.getUser());
        checkPermisions(file, 0400);
    }

    /**
     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
     */
    @Override
    protected String[] getBadListing()
    {

        return (badsamples);
    }

    /**
     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
     */
    @Override
    protected String[] getGoodListing()
    {

        return (goodsamples);
    }

    /**
     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
     */
    @Override
    protected FTPFileEntryParser getParser()
    {
        ConfigurableFTPFileEntryParserImpl parser =
            new VMSFTPEntryParser();
        parser.configure(null);
        return parser;
    }
    protected FTPFileEntryParser getVersioningParser()
    {
        ConfigurableFTPFileEntryParserImpl parser =
            new VMSVersioningFTPEntryParser();
        parser.configure(null);
        return parser;
    }

    /**
     * Method checkPermisions.
     * Verify that the VMS parser does NOT  set the permissions.
     * @param dir
     */
    private void checkPermisions(FTPFile dir, int octalPerm)
    {
        int permMask = 1<<8;
        assertTrue("Owner should not have read permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.USER_ACCESS,
                                      FTPFile.READ_PERMISSION));
        permMask >>= 1;
        assertTrue("Owner should not have write permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.USER_ACCESS,
                                      FTPFile.WRITE_PERMISSION));
        permMask >>= 1;
        assertTrue("Owner should not have execute permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.USER_ACCESS,
                                      FTPFile.EXECUTE_PERMISSION));
        permMask >>= 1;
        assertTrue("Group should not have read permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.GROUP_ACCESS,
                                      FTPFile.READ_PERMISSION));
        permMask >>= 1;
        assertTrue("Group should not have write permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.GROUP_ACCESS,
                                      FTPFile.WRITE_PERMISSION));
        permMask >>= 1;
        assertTrue("Group should not have execute permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.GROUP_ACCESS,
                                      FTPFile.EXECUTE_PERMISSION));
        permMask >>= 1;
        assertTrue("World should not have read permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.WORLD_ACCESS,
                                      FTPFile.READ_PERMISSION));
        permMask >>= 1;
        assertTrue("World should not have write permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.WORLD_ACCESS,
                                      FTPFile.WRITE_PERMISSION));
        permMask >>= 1;
        assertTrue("World should not have execute permission.",
                ((permMask & octalPerm) != 0) == dir.hasPermission(FTPFile.WORLD_ACCESS,
                                      FTPFile.EXECUTE_PERMISSION));
    }
}
