package com.jscape.inet.sftp.protocol.v4.messages;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class Acl {

    public final int type;
    public final Flag flag;
    public final Mask mask;
    public final String who;

    public Acl(int type, Flag flag, Mask mask, String who) {
        this.type = type;

        assertNotNull(flag);
        this.flag = flag;

        assertNotNull(mask);
        this.mask = mask;

        assertNotNull(who);
        this.who = who;
    }

    public Acl(AceType type, Flag flag, Mask mask, String who) {
        this(type.code, flag, mask, who);
    }

    @Override
    public String toString() {
        return "Acl {"
               + "type=" + this.type
               + ", flag=" + this.flag
               + ", mask=" + this.mask
               + ", who='" + this.who + '\''
               + '}';
    }

    public static class Flag {

        public final boolean fileInheritAce;
        public final boolean directoryInheritAce;
        public final boolean noPropagateInheritAce;
        public final boolean inheritOnlyAce;
        public final boolean successfulAccessAceFlag;
        public final boolean failedAccessAceFlag;
        public final boolean identifierGroup;

        public Flag(boolean fileInheritAce,
                    boolean directoryInheritAce,
                    boolean noPropagateInheritAce,
                    boolean inheritOnlyAce,
                    boolean successfulAccessAceFlag,
                    boolean failedAccessAceFlag,
                    boolean identifierGroup) {
            this.fileInheritAce = fileInheritAce;
            this.directoryInheritAce = directoryInheritAce;
            this.noPropagateInheritAce = noPropagateInheritAce;
            this.inheritOnlyAce = inheritOnlyAce;
            this.successfulAccessAceFlag = successfulAccessAceFlag;
            this.failedAccessAceFlag = failedAccessAceFlag;
            this.identifierGroup = identifierGroup;
        }

        @Override
        public String toString() {
            return "Flag {"
                   + "fileInheritAce=" + this.fileInheritAce
                   + ", directoryInheritAce=" + this.directoryInheritAce
                   + ", noPropagateInheritAce=" + this.noPropagateInheritAce
                   + ", inheritOnlyAce=" + this.inheritOnlyAce
                   + ", successfulAccessAceFlag=" + this.successfulAccessAceFlag
                   + ", failedAccessAceFlag=" + this.failedAccessAceFlag
                   + ", identifierGroup=" + this.identifierGroup
                   + '}';
        }
    }

    public static class Mask {

        public final boolean readData;
        public final boolean listDirectory;
        public final boolean writeData;
        public final boolean addFile;
        public final boolean appendData;
        public final boolean addSubdirectory;
        public final boolean readNamedAttrs;
        public final boolean writeNamedAttrs;
        public final boolean execute;
        public final boolean deleteChild;
        public final boolean readAttributes;
        public final boolean writeAttributes;
        public final boolean delete;
        public final boolean readAcl;
        public final boolean writeAcl;
        public final boolean writeOwner;
        public final boolean synchronize;

        public Mask(boolean readData,
                    boolean listDirectory,
                    boolean writeData,
                    boolean addFile,
                    boolean appendData,
                    boolean addSubdirectory,
                    boolean readNamedAttrs,
                    boolean writeNamedAttrs,
                    boolean execute,
                    boolean deleteChild,
                    boolean readAttributes,
                    boolean writeAttributes,
                    boolean delete,
                    boolean readAcl,
                    boolean writeAcl,
                    boolean writeOwner,
                    boolean synchronize) {
            this.readData = readData;
            this.listDirectory = listDirectory;
            this.writeData = writeData;
            this.addFile = addFile;
            this.appendData = appendData;
            this.addSubdirectory = addSubdirectory;
            this.readNamedAttrs = readNamedAttrs;
            this.writeNamedAttrs = writeNamedAttrs;
            this.execute = execute;
            this.deleteChild = deleteChild;
            this.readAttributes = readAttributes;
            this.writeAttributes = writeAttributes;
            this.delete = delete;
            this.readAcl = readAcl;
            this.writeAcl = writeAcl;
            this.writeOwner = writeOwner;
            this.synchronize = synchronize;
        }

        @Override
        public String toString() {
            return "Mask {"
                   + "readData=" + this.readData
                   + ", listDirectory=" + this.listDirectory
                   + ", writeData=" + this.writeData
                   + ", addFile=" + this.addFile
                   + ", appendData=" + this.appendData
                   + ", addSubdirectory=" + this.addSubdirectory
                   + ", readNamedAttrs=" + this.readNamedAttrs
                   + ", writeNamedAttrs=" + this.writeNamedAttrs
                   + ", execute=" + this.execute
                   + ", deleteChild=" + this.deleteChild
                   + ", readAttributes=" + this.readAttributes
                   + ", writeAttributes=" + this.writeAttributes
                   + ", delete=" + this.delete
                   + ", readAcl=" + this.readAcl
                   + ", writeAcl=" + this.writeAcl
                   + ", writeOwner=" + this.writeOwner
                   + ", synchronize=" + this.synchronize
                   + '}';
        }
    }
}
