/*******************************************************************************
 * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc.
 * All rights reserved. This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Red Hat, Inc.
 ******************************************************************************/

package com.openshift.internal.restclient.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;

import com.openshift.internal.restclient.model.image.TagReference;
import com.openshift.restclient.IClient;
import com.openshift.restclient.images.DockerImageURI;
import com.openshift.restclient.model.IImageStream;
import com.openshift.restclient.model.image.ITagReference;

public class ImageStream extends KubernetesResource implements IImageStream {

    private static final String DOCKER_IMAGE_REPO = "spec.dockerImageRepository";
    private static final String STATUS_DOCKER_IMAGE_REPO = "status.dockerImageRepository";
    private static final String SPEC_TAGS = "spec.tags";
    private static final String STATUS_TAGS = "status.tags";
    private static final String TAG = "tag";
    private static final String ITEMS = "items";
    private static final String IMAGE = "image";
    private Map<String, String[]> propertyKeys;

    public ImageStream() {
        this(new ModelNode(), null, null);
    }

    public ImageStream(ModelNode node, IClient client, Map<String, String[]> propertyKeys) {
        super(node, client, propertyKeys);
        this.propertyKeys = propertyKeys;
    }

    @Override
    public void setDockerImageRepository(DockerImageURI uri) {
        setDockerImageRepository(uri.getAbsoluteUri());
    }

    @Override
    public void setDockerImageRepository(String uri) {
        set(DOCKER_IMAGE_REPO, uri);
    }

    @Override
    public DockerImageURI getDockerImageRepository() {
        if (getNode().has(getPath(DOCKER_IMAGE_REPO))) {
            return new DockerImageURI(asString(DOCKER_IMAGE_REPO));
        }
        return new DockerImageURI(asString(STATUS_DOCKER_IMAGE_REPO));
    }

    @Override
    public Collection<String> getTagNames() {
        ModelNode node = get(STATUS_TAGS);
        if (!node.isDefined()) {
            return new ArrayList<>();
        }
        return node.asList().stream().map(n -> asString(n, TAG)).collect(Collectors.toList());
    }

    @Override
    public Collection<ITagReference> getTags() {
        ModelNode node = get(SPEC_TAGS);
        if (!node.isDefined()) {
            return new ArrayList<>();
        }
        return node.asList().stream().map(n -> new TagReference(n, propertyKeys)).collect(Collectors.toList());
    }

    @Override
    public ITagReference addTag(String name, String fromKind, String fromName) {
        TagReference reference = new TagReference(name, fromKind, fromName);
        // add last since its copy of node. future sets will do nothing
        ModelNode tags = get(SPEC_TAGS);
        tags.add(reference.getNode());
        return reference;
    }

    @Override
    public ITagReference addTag(String name, String fromKind, String fromName, String fromNamespace) {
        TagReference reference = new TagReference(name, fromKind, fromName, fromNamespace);
        // add last since its copy of node. future sets will do nothing
        ModelNode tags = get(SPEC_TAGS);
        tags.add(reference.getNode());
        return reference;
    }

    @Override
    public void setTag(String newTag, String fromTag) {
        ModelNode tag = new ModelNode();
        tag.get("name").set(newTag);
        ModelNode from = new ModelNode();
        from.get("kind").set("ImageStreamTag");
        from.get("name").set(fromTag);
        tag.get("from").set(from);
        ModelNode tags = get(SPEC_TAGS);
        tags.add(tag);
    }

    protected String getImageId(List<ModelNode> itemWrappers) {
        for (ModelNode itemWrapper : itemWrappers) {
            ModelNode image = itemWrapper.get(IMAGE);
            if (image != null) {
                return image.asString();
            }
        }
        return null;
    }

    @Override
    public String getImageId(String tagName) {
        String imageId = null;
        ModelNode tags = get(STATUS_TAGS);
        if (tags.getType() != ModelType.LIST || tagName == null) {
            return null;
        }

        List<ModelNode> tagWrappers = tags.asList();
        for (ModelNode tagWrapper : tagWrappers) {
            ModelNode tag = tagWrapper.get(TAG);
            ModelNode items = tagWrapper.get(ITEMS);
            if (tag.asString().equals(tagName) && items.getType() == ModelType.LIST) {
                imageId = getImageId(items.asList());
                break;
            }
        }
        return imageId;
    }

}
