// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.organization;

import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;

import java.util.Objects;
import java.util.Optional;

/**
 * Represents an issue which needs to reported, typically from the controller, to a responsible party,
 * the identity of which is determined by the propertyId and, possibly, assignee fields.
 *
 * @author jvenstad
 */
public class Issue {

    private final String summary;
    private final String description;
    private final String label;
    private final User assignee;
    private final PropertyId propertyId;
    private final Type type;

    private Issue(String summary, String description, String label, User assignee, PropertyId propertyId, Type type) {
        if (summary.isEmpty()) throw new IllegalArgumentException("Issue summary can not be empty!");
        if (description.isEmpty()) throw new IllegalArgumentException("Issue description can not be empty!");
        Objects.requireNonNull(propertyId, "An issue must belong to a property!");

        this.summary = summary;
        this.description = description;
        this.label = label;
        this.assignee = assignee;
        this.propertyId = propertyId;
        this.type = type;
    }

    public Issue(String summary, String description, PropertyId propertyId) {
        this(summary, description, null, null, propertyId, Type.defect);
    }

    public Issue append(String appendage) {
        return new Issue(summary, description + appendage, label, assignee, propertyId, type);
    }

    public Issue with(String label) {
        return new Issue(summary, description, label, assignee, propertyId, type);
    }

    public Issue with(User assignee) {
        return new Issue(summary, description, label, assignee, propertyId, type);
    }

    public Issue with(PropertyId propertyId) {
        return new Issue(summary, description, label, assignee, propertyId, type);
    }

    public Issue with(Type type) {
        return new Issue(summary, description, label, assignee, propertyId, type);
    }

    public String summary() {
        return summary;
    }

    public String description() {
        return description;
    }

    public Optional<String> label() {
        return Optional.ofNullable(label);
    }

    public Optional<User> assignee() {
        return Optional.ofNullable(assignee);
    }

    public PropertyId propertyId() {
        return propertyId;
    }

    public Type type() {
        return type;
    }


    public enum Type {

        defect, // A defect which needs fixing.
        task    // A task the humans must perform.

    }

}

@@ -185,16 +185,64 @@
 ation;%0A%0A
+import com.google.common.collect.ImmutableList;%0A
 import c
@@ -303,16 +303,97 @@
 rtyId;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.List;%0A
 import j
@@ -773,28 +773,35 @@
 e final 
+List%3C
 String
+%3E
  label
+s
 ;%0A    pr
@@ -952,28 +952,35 @@
 iption, 
+List%3C
 String
+%3E
  label
+s
 , User a
@@ -1414,16 +1414,40 @@
 abel
+s
  = 
+ImmutableList.copyOf(
 label
+s)
 ;%0A  
@@ -1662,20 +1662,39 @@
 iption, 
-null
+Collections.emptyList()
 , null, 
@@ -1830,24 +1830,25 @@
 ndage, label
+s
 , assignee, 
@@ -1923,52 +1923,376 @@
     
-return new Issue(summary, description, label
+List%3CString%3E labels = new ArrayList%3C%3E(this.labels);%0A        labels.add(label);%0A        return new Issue(summary, description, labels, assignee, propertyId, type);%0A    %7D%0A%0A    public Issue with(List%3CString%3E labels) %7B%0A        List%3CString%3E newLabels = new ArrayList%3C%3E(this.labels);%0A        newLabels.addAll(labels);%0A        return new Issue(summary, description, newLabels
 , as
@@ -2408,32 +2408,33 @@
 scription, label
+s
 , assignee, prop
@@ -2546,32 +2546,33 @@
 scription, label
+s
 , assignee, prop
@@ -2680,16 +2680,17 @@
 n, label
+s
 , assign
@@ -2860,24 +2860,20 @@
  public 
-Optional
+List
 %3CString%3E
@@ -2878,16 +2878,17 @@
 g%3E label
+s
 () %7B%0A   
@@ -2903,34 +2903,14 @@
 urn 
-Optional.ofNullable(label)
+labels
 ;%0A  

Allow multiple issue labels