package com.kryptnostic.storage.v2.models;

import java.util.UUID;

import javax.annotation.concurrent.Immutable;

import org.joda.time.DateTime;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.kryptnostic.storage.v2.types.TypeUUIDs;
import com.kryptnostic.v2.constants.Names;

/**
 *
 * @author Matthew Tamayo-Rios &lt;matthew@kryptnostic.com&gt;
 *
 */
@Immutable
public class ObjectMetadata {
    protected final UUID     id;
    protected final UUID     type;
    protected final long     version;
    protected final long     size;

    protected final UUID     creator;
    protected final DateTime createdTime;

    @JsonCreator
    public ObjectMetadata(
            @JsonProperty( Names.ID_FIELD ) UUID id,
            @JsonProperty( Names.VERSION_FIELD ) long version,
            @JsonProperty( Names.SIZE_FIELD ) long size,
            @JsonProperty( Names.TYPE_FIELD ) UUID type,
            @JsonProperty( Names.CREATOR_FIELD ) UUID creator,
            @JsonProperty( Names.CREATED_TIME ) DateTime createdTime ) {
        this.id = id;
        this.version = version;
        this.type = type;

        this.creator = creator;

        this.createdTime = createdTime;
        this.size = size;
    }

    public static ObjectMetadata newObject(
             UUID id,
             UUID creator ) {
        return new ObjectMetadata( id, 0, 0, TypeUUIDs.DEFAULT, creator, DateTime.now() );
    }

    public static ObjectMetadata newObject(
             UUID id,
             UUID creator,
             long version ) {
        return new ObjectMetadata( id, version, 0, TypeUUIDs.DEFAULT, creator, DateTime.now() );
    }

    /**
     * @return Document identifier
     */
    @JsonProperty( Names.ID_FIELD )
    public UUID getId() {
        return id;
    }

    /**
     * @return Version of document
     */
    @JsonProperty( Names.VERSION_FIELD )
    public long getVersion() {
        return version;
    }

    @JsonProperty( Names.CREATOR_FIELD )
    public UUID getCreator() {
        return creator;
    }

    @JsonProperty( Names.CREATED_TIME )
    public DateTime getCreatedTime() {
        return createdTime;
    }

    @JsonProperty( Names.TYPE_FIELD )
    public UUID getType() {
        return type;
    }

    @JsonProperty( Names.SIZE_FIELD )
    public long getSize() {
        return size;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ( ( createdTime == null ) ? 0 : createdTime.hashCode() );
        result = prime * result + ( ( creator == null ) ? 0 : creator.hashCode() );
        result = prime * result + ( ( id == null ) ? 0 : id.hashCode() );
        result = prime * result + (int) ( size ^ ( size >>> 32 ) );
        result = prime * result + ( ( type == null ) ? 0 : type.hashCode() );
        result = prime * result + (int) ( version ^ ( version >>> 32 ) );
        return result;
    }

    @Override
    public boolean equals( Object obj ) {
        if ( this == obj ) {
            return true;
        }
        if ( obj == null ) {
            return false;
        }
        if ( !( obj instanceof ObjectMetadata ) ) {
            return false;
        }
        ObjectMetadata other = (ObjectMetadata) obj;
        if ( createdTime == null ) {
            if ( other.createdTime != null ) {
                return false;
            }
        } else if ( !createdTime.equals( other.createdTime ) ) {
            return false;
        }
        if ( creator == null ) {
            if ( other.creator != null ) {
                return false;
            }
        } else if ( !creator.equals( other.creator ) ) {
            return false;
        }
        if ( id == null ) {
            if ( other.id != null ) {
                return false;
            }
        } else if ( !id.equals( other.id ) ) {
            return false;
        }
        if ( size != other.size ) {
            return false;
        }
        if ( type == null ) {
            if ( other.type != null ) {
                return false;
            }
        } else if ( !type.equals( other.type ) ) {
            return false;
        }
        if ( version != other.version ) {
            return false;
        }
        return true;
    }


}

@@ -37,16 +37,42 @@
 odels;%0A%0A
+import java.util.EnumSet;%0A
 import j
@@ -515,16 +515,27 @@
 UID     
+           
 id;%0A    
@@ -559,16 +559,27 @@
 UID     
+           
 type;%0A  
@@ -605,16 +605,27 @@
 ong     
+           
 version;
@@ -654,20 +654,86 @@
 ong     
-size
+           size;%0A    protected EnumSet%3CCryptoMaterial%3E   uploadedParts
 ;%0A%0A    p
@@ -804,24 +804,96 @@
 eatedTime;%0A%0A
+    public enum CryptoMaterial %7B%0A        IV, TAG, CONTENTS, SALT%0A    %7D%0A%0A
     @JsonCre
@@ -2588,32 +2588,238 @@
 rn size;%0A    %7D%0A%0A
+    public boolean updateUploadProgress( CryptoMaterial nextUploaded ) %7B%0A        uploadedParts.add( nextUploaded );%0A        return uploadedParts.containsAll( EnumSet.allOf( CryptoMaterial.class ) );%0A    %7D%0A%0A
     @Override%0A  

add an enumset to indicate whether an objectMetadata has finished being fully constructed