/*
 * Copyright 2011 Erlend Hamnaberg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.hamnaberg.json;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import java.net.URI;
import java.util.Collection;

public class DefaultJsonCollection extends AbstractJsonCollection {
    private final ImmutableList<Link> links;
    private final ImmutableList<Item> items;
    private final ImmutableList<Query> queries;
    private final Template template;

    public DefaultJsonCollection(URI href) {
        this(href, Version.ONE);
    }

    public DefaultJsonCollection(URI href, Version version) {
        this(href, version, ImmutableList.<Link>of(), ImmutableList.<Item>of(), ImmutableList.<Query>of(), null);
    }

    public DefaultJsonCollection(URI href, Version version, ImmutableList<Link> links, ImmutableList<Item> items, ImmutableList<Query> queries, Template template) {
        super(href, version);
        this.links = links;
        this.items = items;
        this.queries = queries;
        this.template = template;
    }

    @Override
    public ImmutableList<Link> getLinks() {
        return links;
    }

    @Override
    public ImmutableList<Item> getItems() {
        return items;
    }

    @Override
    public boolean hasError() {
        return false;
    }

    @Override
    public ImmutableList<Query> getQueries() {
        return queries;
    }

    @Override
    public boolean hasTemplate() {
        return template != null;
    }

    public Link findLink(Predicate<Link> predicate) {
        return find(links, predicate);
    }

    public Collection<Link> findLinks(Predicate<Link> predicate) {
        return Collections2.filter(links, predicate);
    }

    public Item findItem(Predicate<Item> predicate) {
        return find(items, predicate);
    }

    public Collection<Item> findItems(Predicate<Item> predicate) {
        return Collections2.filter(items, predicate);
    }

    public Query findQuery(Predicate<Query> predicate) {
        return find(queries, predicate);
    }

    public Collection<Query> findQueries(Predicate<Query> predicate) {
        return Collections2.filter(queries, predicate);
    }

    private <T> T find(Collection<T> collection, Predicate<T> predicate) {
        Collection<T> filter = Collections2.filter(collection, predicate);
        if (filter.isEmpty()) {
            return null;
        }
        return filter.iterator().next();
    }

    public Item getFirst() {
        if (items.isEmpty()) {
            return null;
        }
        return items.get(0);
    }

    @Override
    public Template getTemplate() {
        return template;
    }

    @Override
    public ErrorMessage getError() {
        throw new UnsupportedOperationException("Incorrect Collection type.");
    }
}

@@ -1354,32 +1354,223 @@
 , null);%0A    %7D%0A%0A
+    public DefaultJsonCollection(URI href, Version version, ImmutableList%3CItem%3E items) %7B%0A        this(href, version, ImmutableList.%3CLink%3Eof(), items, ImmutableList.%3CQuery%3Eof(), null);%0A    %7D%0A%0A
     public Defau
@@ -3615,11 +3615,1705 @@
 );%0A    %7D
+%0A%0A    public static class Builder %7B%0A        private final URI href;%0A        private Version version = Version.ONE;%0A        private final ImmutableList.Builder%3CItem%3E itemBuilder = ImmutableList.builder();%0A        private final ImmutableList.Builder%3CLink%3E linkBuilder = ImmutableList.builder();%0A        private final ImmutableList.Builder%3CQuery%3E queryBuilder = ImmutableList.builder();%0A        private Template template;%0A%0A        public Builder(URI href) %7B%0A            this.href = href;%0A        %7D%0A%0A        public Builder withVersion(Version version) %7B%0A            this.version = version;%0A            return this;%0A        %7D%0A%0A        public Builder withTemplate(Template template) %7B%0A            this.template = template;%0A            return this;%0A        %7D%0A%0A        public Builder addItem(Item item) %7B%0A            itemBuilder.add(item);%0A            return this;%0A        %7D%0A%0A        public Builder addItems(Iterable%3CItem%3E items) %7B%0A            itemBuilder.addAll(items);%0A            return this;%0A        %7D%0A%0A        public Builder addQuery(Query query) %7B%0A            queryBuilder.add(query);%0A            return this;%0A        %7D%0A%0A        public Builder addQueries(Iterable%3CQuery%3E queries) %7B%0A            queryBuilder.addAll(queries);%0A            return this;%0A        %7D%0A%0A        public Builder addLink(Link link) %7B%0A            linkBuilder.add(link);%0A            return this;%0A        %7D%0A%0A        public Builder addLinks(Iterable%3CLink%3E links) %7B%0A            linkBuilder.addAll(links);%0A            return this;%0A        %7D%0A%0A        public JsonCollection build() %7B%0A            return new DefaultJsonCollection(href, version, linkBuilder.build(), itemBuilder.build(), queryBuilder.build(), template);%0A        %7D%0A    %7D
 %0A%7D%0A

Add another constructor