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

import com.jscape.inet.sftp.protocol.v4.messages.FileAttributeFlags;

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

    public static FileAttributeFlags parse(int data) {
        return new FileAttributeFlags(Mask.SSH_FILEXFER_ATTR_SIZE.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_PERMISSIONS.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_ACCESSTIME.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_CREATETIME.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_MODIFYTIME.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_ACL.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_OWNERGROUP.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_SUBSECOND_TIMES.presentIn(data),
                                      Mask.SSH_FILEXFER_ATTR_EXTENDED.presentIn(data));
    }

    public static int format(FileAttributeFlags value) {
        int data = 0;
        data = Mask.SSH_FILEXFER_ATTR_SIZE.set(value.sizeAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_PERMISSIONS.set(value.permissionsAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_ACCESSTIME.set(value.accessTimeAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_CREATETIME.set(value.createTimeAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_MODIFYTIME.set(value.modifyTimeAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_ACL.set(value.aclAttributePresent, data);
        data = Mask.SSH_FILEXFER_ATTR_OWNERGROUP.set(value.ownerGroupAttributesPresent, data);
        data = Mask.SSH_FILEXFER_ATTR_SUBSECOND_TIMES.set(value.subsecondTimesPresent, data);
        data = Mask.SSH_FILEXFER_ATTR_EXTENDED.set(value.extendedAttributesPresent, data);

        return data;
    }

    private FileAttributeFlagsFormat() {
    }

    public enum Mask {

        SSH_FILEXFER_ATTR_SIZE(0x00000001),
        SSH_FILEXFER_ATTR_PERMISSIONS(0x00000004),
        SSH_FILEXFER_ATTR_ACCESSTIME(0x00000008),
        SSH_FILEXFER_ATTR_CREATETIME(0x00000010),
        SSH_FILEXFER_ATTR_MODIFYTIME(0x00000020),
        SSH_FILEXFER_ATTR_ACL(0x00000040),
        SSH_FILEXFER_ATTR_OWNERGROUP(0x00000080),
        SSH_FILEXFER_ATTR_SUBSECOND_TIMES(0x00000100),
        SSH_FILEXFER_ATTR_EXTENDED(0x80000000);

        public final int code;

        Mask(int code) {
            this.code = code;
        }

        public boolean presentIn(int flags) {
            return (flags & this.code) == this.code;
        }

        public int set(boolean value, int flags) {
            return value ? flags | this.code : flags;
        }
    }
}
