package com.pingcap.kb.integration.jira;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.pingcap.kb.integration.config.JiraConfiguration;
import com.pingcap.kb.integration.jira.JiraUpdate.Update.StringField;
import com.pingcap.kb.integration.jira.JiraUpdate.Update.StringListField;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Builder;
import lombok.Data;

@Data
public class JiraUpdate {

  private Update update = new Update();

  public JiraUpdate addLabel(String label) {
    update.getLabels().add(StringListField.add(label));
    return this;
  }

  public JiraUpdate removeLabel(String label) {
    update.getLabels().add(StringListField.remove(label));
    return this;
  }

  public JiraUpdate setKbLink(JiraConfiguration config, String link) {
    config.getCustomFields().forEach((k, v) -> {
      if (v.equals("kbLink")) {
        update.getCustomFields().put(k, Collections.singleton(StringField.set(link)));
      }
    });
    return this;
  }

  @Data
  public static class Update {

    private List<StringListField> labels = new ArrayList<>();

    @JsonIgnore
    private Map<String, Object> customFields = new HashMap<>();

    @JsonAnyGetter
    public Map<String, Object> getMap() {
      return customFields;
    }

    @Builder
    @Data
    public static class StringField {

      private String set;

      public static StringField set(String value) {
        return StringField.builder().set(value).build();
      }
    }

    @JsonInclude(Include.NON_NULL)
    @Data
    @Builder
    public static class StringListField {

      private String add;
      private String remove;

      public static StringListField add(String value) {
        return StringListField.builder().add(value).build();
      }

      public static StringListField remove(String value) {
        return StringListField.builder().remove(value).build();
      }
    }
  }
}
