/*
 * Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.frontend.configuration;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.lang.StringUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * Configuration for a Redis server. This allows both a single Redis or a Redis Sentinel configuration
 */
@Data
@JsonDeserialize(builder = RedisConfig.Builder.class)
public class RedisConfig {
    private final String masterName;
    private final String password;
    private final HostAndPort address;
    private final Set<HostAndPort> sentinels;

    private RedisConfig(final Builder builder) {
        masterName = builder.masterName;
        password = builder.password;
        address = builder.address;
        sentinels = builder.sentinels;
    }

    /**
     * Validates the configuration
     * @throws ConfigException If either:
     * <li>address is non null and invalid, and sentinels is null or empty </li>
     * <li>sentinels is non null and non empty and masterName is null or blank</li>
     */
    public void basicValidate() throws ConfigException {
        if ((address != null && !address.validate()) && (sentinels == null || sentinels.isEmpty())) {
            throw new ConfigException("redis", "Redis configuration requires either an address or at least one sentinel to connect to");
        }

        if (sentinels != null && !sentinels.isEmpty() && StringUtils.isBlank(masterName)) {
            throw new ConfigException("redis", "Redis configuration requires a masterName when connecting to sentinel");
        }
    }

    /**
     * Creates a new RedisConfig using values from this with missing values supplied by other
     * @param other The other Redis configuration
     * @return The new merged Redis config
     */
    public RedisConfig merge(final RedisConfig other) {
        final Builder builder = new Builder(this);
        if (masterName == null) builder.masterName = other.masterName;
        if (password == null) builder.password = other.password;
        if (sentinels == null) builder.sentinels = other.sentinels;
        builder.address = address == null ? other.address : address.merge(other.address);
        return builder.build();
    }

    @Data
    @NoArgsConstructor
    @Accessors(chain = true)
    @JsonPOJOBuilder(withPrefix = "set")
    public static class Builder {
        private String masterName;
        private String password;
        private HostAndPort address;
        private Set<HostAndPort> sentinels;

        public Builder(final RedisConfig config) {
            masterName = config.masterName;
            password = config.password;
            address = config.address;
            sentinels = config.sentinels;
        }

        public RedisConfig build() {
            return new RedisConfig(this);
        }
    }
}

@@ -503,34 +503,8 @@
 s;%0A%0A
-import java.util.HashSet;%0A
 impo
@@ -521,16 +521,16 @@
 il.Set;%0A
+
 %0A/**%0A * 
@@ -872,24 +872,60 @@
 %3E sentinels;
+%0A    private final Integer database;
 %0A%0A    privat
@@ -1111,24 +1111,61 @@
 .sentinels;%0A
+        database = builder.database;%0A
     %7D%0A%0A    /
@@ -2460,32 +2460,97 @@
 ther.sentinels;%0A
+        if (database == null) builder.database = other.database;%0A
         builder.
@@ -2947,16 +2947,50 @@
 ntinels;
+%0A        private Integer database;
 %0A%0A      
@@ -3148,32 +3148,32 @@
 config.address;%0A
-
             sent
@@ -3190,32 +3190,72 @@
 nfig.sentinels;%0A
+            database = config.database;%0A
         %7D%0A%0A     

Make it possible to configure the Redis database. Defaults to null. [rev: matthew.gordon]