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

import com.jscape.util.Clock;
import com.jscape.util.file.PosixFilePermissions;
import com.jscape.util.file.UnixFileType;

import java.util.HashMap;
import java.util.Map;

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

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

    public static final long TIME_FACTOR = 1000L;

    public final Long size;
    public final Integer userId;
    public final Integer groupId;
    public final UnixFileType fileType;
    public final PosixFilePermissions permissions;
    public final Integer accessTime;
    public final Integer modificationTime;
    public final Map<String, String> extendedData;

    public static FileAttributes empty() {
        return new FileAttributes(null, null, null, null);
    }

    public static FileAttributes attributesFor(long lastModificationDate) {
        return new FileAttributes(null, null, null, (int) (lastModificationDate / TIME_FACTOR));
    }

    public static FileAttributes attributesFor(PosixFilePermissions permissions) {
        return new FileAttributes(null, null, null, null, permissions, null, null, new HashMap<String, String>());
    }

    public FileAttributes(Long size,
                          Integer userId,
                          Integer groupId,
                          UnixFileType fileType,
                          PosixFilePermissions permissions,
                          Integer accessTime,
                          Integer modificationTime,
                          Map<String, String> extendedData) {
        this.size = size;
        this.userId = userId;
        this.groupId = groupId;
        this.fileType = fileType;
        this.permissions = permissions;
        this.accessTime = accessTime;
        this.modificationTime = modificationTime;

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

    public FileAttributes(Long size, UnixFileType fileType, PosixFilePermissions permissions, Integer modificationTime) {
        this(size, null, null, fileType, permissions, modificationTime, modificationTime, new HashMap<String, String>());
    }

    public UnixFileType type() {
        return this.fileType != null ? this.fileType : UnixFileType.REGULAR;
    }

    public long size() {
        return this.size != null ? this.size : 0L;
    }

    public boolean readable() {
        return this.permissions != null && this.permissions.ownerCanRead;
    }

    public boolean writable() {
        return this.permissions != null && this.permissions.ownerCanWrite;
    }

    public long accessTime() {
        return this.accessTime != null ? this.accessTime * TIME_FACTOR : Clock.now();
    }

    public long modificationTime() {
        return this.modificationTime != null ? this.modificationTime * TIME_FACTOR : Clock.now();
    }

    @Override
    public String toString() {
        return "FileAttributes {"
                + "size=" + this.size
                + ", userId=" + this.userId
                + ", groupId=" + this.groupId
                + ", fileType=" + this.fileType
                + ", permissions=" + this.permissions
                + ", accessTime=" + this.accessTime
                + ", modificationTime=" + this.modificationTime
                + ", extendedData=" + this.extendedData
                + '}';
    }
}
