package com.box.sdk;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;

public abstract class BoxItem extends BoxResource {
    public BoxItem(BoxAPIConnection api, String id) {
        super(api, id);
    }

    public abstract class Info<T extends BoxItem> extends BoxResource.Info<T> {
        private String sequenceID;
        private String etag;
        private String name;
        private Date createdAt;
        private Date modifiedAt;
        private String description;
        private long size;
        private List<BoxFolder> pathCollection;
        private BoxUser.Info createdBy;
        private BoxUser.Info modifiedBy;
        private Date trashedAt;
        private Date purgedAt;
        private Date contentCreatedAt;
        private Date contentModifiedAt;
        private BoxUser.Info ownedBy;

        public Info(JsonObject jsonObject) {
            for (JsonObject.Member member : jsonObject) {
                if (member.getValue().isNull()) {
                    continue;
                }

                this.parseJsonMember(member);
            }
        }

        public String getEtag() {
            return this.etag;
        }

        public String getName() {
            return this.name;
        }

        public Date getCreatedAt() {
            return this.createdAt;
        }

        public Date getModifiedAt() {
            return this.modifiedAt;
        }

        public String getDescription() {
            return this.description;
        }

        public long getSize() {
            return this.size;
        }

        public List<BoxFolder> getPathCollection() {
            return this.pathCollection;
        }

        public BoxUser.Info getCreatedBy() {
            return this.createdBy;
        }

        public BoxUser.Info getModifiedBy() {
            return this.modifiedBy;
        }

        public Date getTrashedAt() {
            return this.trashedAt;
        }

        public Date getPurgedAt() {
            return this.purgedAt;
        }

        public Date getContentCreatedAt() {
            return this.createdAt;
        }

        public Date getContentModifiedAt() {
            return this.contentModifiedAt;
        }

        public BoxUser.Info getOwnedBy() {
            return this.ownedBy;
        }

        public String getSequenceID() {
            return this.sequenceID;
        }

        protected void parseJsonMember(JsonObject.Member member) {
            try {
                JsonValue value = member.getValue();
                switch (member.getName()) {
                    case "sequence_id":
                        this.sequenceID = value.asString();
                        break;
                    case "etag":
                        this.etag = value.asString();
                        break;
                    case "name":
                        this.name = value.asString();
                        break;
                    case "created_at":
                        this.createdAt = BoxDateParser.parse(value.asString());
                        break;
                    case "modified_at":
                        this.modifiedAt = BoxDateParser.parse(value.asString());
                        break;
                    case "description":
                        this.description = value.asString();
                        break;
                    case "size":
                        this.size = value.asLong();
                        break;
                    case "trashed_at":
                        this.trashedAt = BoxDateParser.parse(value.asString());
                        break;
                    case "purged_at":
                        this.purgedAt = BoxDateParser.parse(value.asString());
                        break;
                    case "content_created_at":
                        this.contentCreatedAt = BoxDateParser.parse(value.asString());
                        break;
                    case "content_modified_at":
                        this.contentModifiedAt = BoxDateParser.parse(value.asString());
                        break;
                    case "path_collection":
                        this.pathCollection = this.parsePathCollection(value.asObject());
                        break;
                    case "created_by":
                        this.createdBy = this.parseUserInfo(value.asObject());
                        break;
                    case "modified_by":
                        this.modifiedBy = this.parseUserInfo(value.asObject());
                        break;
                    case "owned_by":
                        this.ownedBy = this.parseUserInfo(value.asObject());
                        break;
                    default:
                        break;
                }
            } catch (ParseException e) {
                assert false : "A ParseException indicates a bug in the SDK.";
            }
        }

        private List<BoxFolder> parsePathCollection(JsonObject jsonObject) {
            int count = jsonObject.get("total_count").asInt();
            List<BoxFolder> pathCollection = new ArrayList<BoxFolder>(count);
            JsonArray entries = jsonObject.get("entries").asArray();
            for (JsonValue value : entries) {
                JsonObject entry = value.asObject();
                String id = entry.get("id").asString();
                pathCollection.add(new BoxFolder(getAPI(), id));
            }

            return pathCollection;
        }

        private BoxUser.Info parseUserInfo(JsonObject jsonObject) {
            String userID = jsonObject.get("id").asString();
            BoxUser user = new BoxUser(getAPI(), userID);
            return user.new Info(jsonObject);
        }
    }
}

@@ -994,16 +994,51 @@
 ownedBy;
+%0A        private List%3CString%3E tags;
 %0A%0A      
@@ -2591,32 +2591,113 @@
 eID;%0A        %7D%0A%0A
+        public List%3CString%3E getTags() %7B%0A            return this.tags;%0A        %7D%0A%0A
         protecte
@@ -5011,32 +5011,165 @@
          break;%0A
+                    case %22tags%22:%0A                        this.tags = this.parseTags(value.asArray());%0A                        break;%0A
                 
@@ -6130,16 +6130,16 @@
 serID);%0A
-
         
@@ -6181,21 +6181,299 @@
 );%0A        %7D
+%0A%0A        private List%3CString%3E parseTags(JsonArray jsonArray) %7B%0A            List%3CString%3E tags = new ArrayList%3CString%3E(jsonArray.size());%0A            for (JsonValue value : jsonArray) %7B%0A                tags.add(value.asString());%0A            %7D%0A%0A            return tags;%0A        %7D
 %0A    %7D%0A%7D%0A

Add tags field for BoxItems