package stroom.util.sysinfo;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@JsonInclude(Include.NON_DEFAULT)
@JsonPropertyOrder(alphabetic = true)
public class SystemInfoResult {

    @NotNull
    @JsonProperty("name")
    private final String name;

    @JsonProperty("description")
    private final String description;

    @JsonProperty("details")
    private final Map<String, Object> detailsMap;

    @JsonCreator
    public SystemInfoResult(@JsonProperty("name") final String name,
                            @JsonProperty("description") final String description,
                            @JsonProperty("details") final Map<String, Object> detailsMap) {
        this.name = name;
        this.description = description;
        this.detailsMap = Objects.requireNonNull(detailsMap);
    }

    public Map<String, Object> getDetails() {
        return detailsMap;
    }

    public String getName() {
        return name;
    }

//        public static SystemInfoResult merge(final String name,
//                                             final Collection<SystemInfoResult> systemInfoResults) {
//        long distinctNames = systemInfoResults.stream()
//                .map(SystemInfoResult::getName)
//                .distinct()
//                .count();
//
//        if (systemInfoResults.size() != distinctNames) {
//            throw new RuntimeException("Non unique names found");
//        }
//
//        final Builder builder = SystemInfoResult.builder(name);
//        systemInfoResults.forEach(systemInfoResult -> {
//            builder.withDetail(systemInfoResult.getName(), systemInfoResult);
//        });
//        return builder.build();
//    }

    public static Builder builder(final String name) {
        return new Builder(name);
    }

    @Override
    public String toString() {
        return "SystemInfoResult{" +
                "name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", detailMap=" + detailsMap +
                '}';
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final SystemInfoResult that = (SystemInfoResult) o;
        return name.equals(that.name) &&
                Objects.equals(description, that.description) &&
                detailsMap.equals(that.detailsMap);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, description, detailsMap);
    }

    public static class Builder {

        private final String name;
        private String description = null;
        private final Map<String, Object> detailMap = new HashMap<>();

        public Builder(final String name) {
            this.name = name;
        }

        public Builder withDescription(final String description) {
            this.description = description;
            return this;
        }

        public Builder withDetail(final String key, final Object value) {
            Objects.requireNonNull(key);
            detailMap.put(key, value);
            return this;
        }

        public Builder withError(final Throwable error) {
            Objects.requireNonNull(error);
            detailMap.put("error", error.getMessage());

            return this;
        }

        public Builder withError(final String error) {
            Objects.requireNonNull(error);
            detailMap.put("error", error);

            return this;
        }

        public SystemInfoResult build() {
            if (detailMap.isEmpty()) {
                return new SystemInfoResult(name, description, Collections.emptyMap());
            } else {
                return new SystemInfoResult(name, description, detailMap);
            }
        }
    }
}

@@ -776,19 +776,16 @@
  details
-Map
 ;%0A%0A    @
@@ -1034,19 +1034,16 @@
  details
-Map
 ) %7B%0A    
@@ -1124,19 +1124,16 @@
 .details
-Map
  = Objec
@@ -1153,27 +1153,24 @@
 Null(details
-Map
 );%0A    %7D%0A%0A  
@@ -1235,19 +1235,16 @@
  details
-Map
 ;%0A    %7D%0A
@@ -1302,22 +1302,16 @@
 %0A    %7D%0A%0A
-//    
     publ
@@ -1317,725 +1317,62 @@
 lic 
-static SystemInfoResult merge(final String name,%0A//                                             final Collection%3CSystemInfoResult%3E systemInfoResults) %7B%0A//        long distinctNames = systemInfoResults.stream()%0A//                .map(SystemInfoResult::getName)%0A//                .distinct()%0A//                .count();%0A//%0A//        if (systemInfoResults.size() != distinctNames) %7B%0A//            throw new RuntimeException(%22Non unique names found%22);%0A//        %7D%0A//%0A//        final Builder builder = SystemInfoResult.builder(name);%0A//        systemInfoResults.forEach(systemInfoResult -%3E %7B%0A//            builder.withDetail(systemInfoResult.getName(), systemInfoResult);%0A//        %7D);%0A//        return builder.build();%0A//
+String getDescription() %7B%0A        return description;%0A
     
@@ -1675,19 +1675,17 @@
 , detail
-Map
+s
 =%22 + det
@@ -1688,19 +1688,16 @@
  details
-Map
  +%0A     
@@ -2069,19 +2069,16 @@
  details
-Map
 .equals(
@@ -2085,27 +2085,24 @@
 that.details
-Map
 );%0A    %7D%0A%0A  
@@ -2195,19 +2195,16 @@
  details
-Map
 );%0A    %7D

Fix json serialisation