/*
 * @(#)FileTransferRemoteFile.java
 *
 * Copyright (c) 1999-2007 JSCAPE LLC
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JSCAPE.
 */
package com.jscape.filetransfer;

import java.util.Comparator;
import java.util.Date;

/**
 * Represents a file returned in a remote directory listing.
 */
public class FileTransferRemoteFile {

    public static final Filter FILE_FILTER = new Filter() {
        public boolean accept(FileTransferRemoteFile pathname) {
            return !pathname.isDirectory();
        }
    };

    public static final Filter DIRECTORY_FILTER = new Filter() {
        public boolean accept(FileTransferRemoteFile pathname) {
            return pathname.isDirectory();
        }
    };

    /**
     * filename.
     */
    private String filename;
    /**
     * link target.
     */
    private String linkTarget;
    /**
     * directory.
     */
    private boolean directory;
    /**
     * link.
     */
    private boolean link;
    /**
     * filesize.
     */
    private long filesize;
    /**
     * file date.
     */
    private Date fileDate;
    /**
     * Is the file readable?
     */
    private boolean readable;
    /**
     * Is the file writable?
     */
    private boolean writable;
    /**
     * Is the year set?
     */
    private boolean yearSet;

    /**
     * Constructor.
     *
     * @param filename
     * @param linkTarget
     * @param directory
     * @param link
     * @param filesize
     * @param fileDate
     * @param readable
     * @param writable
     * @param yearSet
     */
    public FileTransferRemoteFile(String filename,
                                  String linkTarget,
                                  boolean directory,
                                  boolean link,
                                  long filesize,
                                  Date fileDate,
                                  boolean readable,
                                  boolean writable,
                                  boolean yearSet) {
        this.filename = filename;
        this.linkTarget = linkTarget;
        this.directory = directory;
        this.link = link;
        this.filesize = filesize;
        this.fileDate = fileDate;
        this.readable = readable;
        this.writable = writable;
        this.yearSet = yearSet;
    }

    /**
     * Constructor.
     *
     * @param filename   filename
     * @param linkTarget linkTarget
     * @param directory  directory
     * @param link       link
     * @param filesize   filesize
     * @param fileDate   fileDate
     * @param readable   readable
     * @param writable   writable
     */
    public FileTransferRemoteFile(String filename,
                                  String linkTarget,
                                  boolean directory,
                                  boolean link,
                                  long filesize,
                                  Date fileDate,
                                  boolean readable,
                                  boolean writable) {
        this(filename, linkTarget, directory, link, filesize, fileDate, readable, writable, false);
    }

    /**
     * Empty constructor.
     */
    public FileTransferRemoteFile() {
        this(null, null, false, false, 0L, null, true, true, false);
    }

    /**
     * Gets filename.
     *
     * @return filename
     */
    public String getFilename() {
        return this.filename;
    }

    /**
     * Sets remote filename.
     *
     * @param value filename
     */
    public void setFilename(String value) {
        this.filename = value;
    }

    /**
     * Gets target of symbolic link.
     *
     * @return path or null if not a symbolic link
     */
    public String getLinkTarget() {
        return this.linkTarget;
    }

    /**
     * Sets link target.
     *
     * @param string target path of symbolic link
     */
    public void setLinkTarget(String string) {
        this.linkTarget = string;
    }

    /**
     * Checks if remote file is a directory.
     *
     * @return true if is a directory, false otherwise
     */
    public boolean isDirectory() {
        return this.directory;
    }

    /**
     * Sets if file is a directory.
     *
     * @param value true if directory, false otherwise
     */
    public void setDirectory(boolean value) {
        this.directory = value;
    }

    /**
     * Checks if remote files is a symbolic link.
     *
     * @return true if symbolic link, false otherwise
     */
    public boolean isLink() {
        return this.link;
    }

    /**
     * Sets if is a symbolic link.
     *
     * @param value true if symbolic link, false otherwise
     */
    public void setLink(boolean value) {
        this.link = value;
    }

    /**
     * Gets filesize.
     *
     * @return filesize in bytes
     */
    public long getFilesize() {
        return this.filesize;
    }

    /**
     * Sets remote filesize.
     *
     * @param value filesize in bytes
     */
    public void setFilesize(long value) {
        this.filesize = value;
    }

    /**
     * Gets the last modified date file.
     *
     * @return Returns the last modified date
     */
    public Date getFileDate() {
        return this.fileDate;
    }

    /**
     * Sets the last modified date file.
     *
     * @param value The last modified date
     */
    public void setFileDate(Date value) {
        this.fileDate = value;
    }

    /**
     * Checks if filename is readable.
     *
     * @return <code>true</code> if filename is readable;
     */
    public boolean isReadable() {
        return this.readable;
    }

    /**
     * Sets filename "readable" flag.
     *
     * @param value if <code>true</code> filename will be marked as readable.
     */
    public void setReadable(boolean value) {
        this.readable = value;
    }

    /**
     * Checks if filename is writable.
     *
     * @return <code>true</code> if filename is writable;
     */
    public boolean isWritable() {
        return this.writable;
    }

    /**
     * Sets filename "writable" flag.
     *
     * @param value if <code>true</code> filename will be marked as writable
     */
    public void setWritable(boolean value) {
        this.writable = value;
    }

    /**
     * Checks if the filename is a hidden filename by checking to see if filename begins with a period.
     *
     * @return true if hidden, false otherwise
     */
    public boolean isHidden() {
        return filename.startsWith(".");
    }

    /**
     * Is year set?
     *
     * @return yearSet
     */
    public boolean getIsYearSet() {
        return this.yearSet;
    }

    /**
     * Is the year of the file date set?
     *
     * @param value
     */
    public void setIsYearSet(boolean value) {
        this.yearSet = value;
    }

    @Override
    public String toString() {
        return "FileTransferRemoteFile {"
                + "filename='" + this.filename + '\''
                + ", linkTarget='" + this.linkTarget + '\''
                + ", directory=" + this.directory
                + ", link=" + this.link
                + ", filesize=" + this.filesize
                + ", fileDate=" + this.fileDate
                + ", readable=" + this.readable
                + ", writable=" + this.writable
                + ", yearSet=" + this.yearSet
                + '}';
    }

    public interface Filter {

        boolean accept(FileTransferRemoteFile pathname);

    }

    public static class NaturalComparator
            implements Comparator<FileTransferRemoteFile> {

        @Override
        public int compare(FileTransferRemoteFile leftPath, FileTransferRemoteFile rightPath) {
            if (leftPath.directory && !rightPath.directory) {
                return -1;
            } else if (rightPath.directory && !leftPath.directory) {
                return 1;
            } else {
                return leftPath.filename.compareTo(rightPath.filename);
            }
        }
    }
}
