content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.cassandra.sidecar.common.response;
  
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  
  import com.fasterxml.jackson.annotation.JsonProperty;
  import org.apache.cassandra.sidecar.common.request.TokenRangeReplicasRequest;
  
  /**
   * Class response for the {@link TokenRangeReplicasRequest}
   */
  public class TokenRangeReplicasResponse
  {
      private final List<ReplicaInfo> writeReplicas;
      private final List<ReplicaInfo> readReplicas;
  
      private final Map<String, ReplicaMetadata> replicaMetadata;
  
      /**
       * Constructs token range replicas response object with given params.
       *
       * @param writeReplicas   list of write replicas {@link ReplicaInfo} instances breakdown by token range
       * @param readReplicas    list of read replica {@link ReplicaInfo} instances breakdown by token range
       * @param replicaMetadata mapping replica to it's state and status information
       */
      public TokenRangeReplicasResponse(@JsonProperty("writeReplicas") List<ReplicaInfo> writeReplicas,
                                        @JsonProperty("readReplicas") List<ReplicaInfo> readReplicas,
                                        @JsonProperty("replicaMetadata") Map<String, ReplicaMetadata> replicaMetadata)
      {
          this.writeReplicas = writeReplicas;
          this.readReplicas = readReplicas;
          this.replicaMetadata = replicaMetadata;
      }
  
      /**
       * @return metadata associated with each replica
       */
      @JsonProperty("replicaMetadata")
      public Map<String, ReplicaMetadata> replicaMetadata()
      {
          return replicaMetadata;
      }
  
      /**
       * @return the {@link ReplicaInfo} instances representing write replicas for each token range
       */
      @JsonProperty("writeReplicas")
      public List<ReplicaInfo> writeReplicas()
      {
          return writeReplicas;
      }
  
      /**
       * @return the {@link ReplicaInfo} instances representing read replicas for each token range
       */
      @JsonProperty("readReplicas")
      public List<ReplicaInfo> readReplicas()
      {
          return readReplicas;
      }
  
      /**
       * Class representing replica instances for a token range grouped by datacenter
       */
      public static class ReplicaInfo
      {
          // exclusive
          private final String start;
          // inclusive
          private final String end;
          private final Map<String, List<String>> replicasByDatacenter;
  
          public ReplicaInfo(@JsonProperty("start") String start,
                             @JsonProperty("end") String end,
                             @JsonProperty("replicas") Map<String, List<String>> replicasByDatacenter)
          {
              this.start = start;
              this.end = end;
              this.replicasByDatacenter = replicasByDatacenter;
          }
  
          /**
           * @return the start value of the token range, exclusive
           */
          @JsonProperty("start")
          public String start()
          {
              return start;
          }
  
          /**
           * @return the end value of the token range, inclusive
           */
          @JsonProperty("end")
          public String end()
          {
              return end;
          }
  
          /**
           * @return mapping of datacenter to a list of replicas that map to the token range
           */
          @JsonProperty("replicasByDatacenter")
          public Map<String, List<String>> replicasByDatacenter()
          {
              return replicasByDatacenter;
          }
  
          /**
           * {@inheritDoc}
           */
          @Override
          public boolean equals(Object o)
          {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              ReplicaInfo that = (ReplicaInfo) o;
              return start.equals(that.start)
                     && end.equals(that.end)
                     && replicasByDatacenter.equals(that.replicasByDatacenter);
          }
  
          /**
           * {@inheritDoc}
           */
          @Override
          public int hashCode()
          {
              return Objects.hash(start, end, replicasByDatacenter);
          }
  
          /**
           * {@inheritDoc}
           */
          @Override
          public String toString()
          {
              return "ReplicaInfo{" +
                     "start='" + start + '\'' +
                     ", end='" + end + '\'' +
                     ", replicasByDatacenter=" + replicasByDatacenter +
                     '}';
          }
      }
  
      /**
       * Class representing metadata associated with replica instances
       */
      public static class ReplicaMetadata
      {
          private final String state;
          private final String status;
          private final String fqdn;
          private final String address;
          private final int port;
          private final String datacenter;
  
          public ReplicaMetadata(@JsonProperty("state") String state,
                                 @JsonProperty("status") String status,
                                 @JsonProperty("fqdn") String fqdn,
                                 @JsonProperty("address") String address,
                                 @JsonProperty("port") int port,
                                 @JsonProperty("datacenter") String datacenter)
          {
              this.state = state;
              this.status = status;
              this.fqdn = fqdn;
              this.address = address;
              this.port = port;
              this.datacenter = datacenter;
          }
  
          /**
           * @return the node state. eg. NORMAL, JOINING, LEAVING, etc.
           */
          @JsonProperty("state")
          public String state()
          {
              return state;
          }
  
          /**
           * @return the node status. eg. UP, DOWN
           */
          @JsonProperty("status")
          public String status()
          {
              return status;
          }
  
          /**
           * @return FQDN of the node
           */
          @JsonProperty("fqdn")
          public String fqdn()
          {
              return fqdn;
          }
  
          /**
           * @return IP address of the node
           */
          @JsonProperty("address")
          public String address()
          {
              return address;
          }
  
          /**
           * @return port number of the node as specified by the replica-set returned
           */
          @JsonProperty("port")
          public int port()
          {
              return port;
          }
  
          /**
           * @return datacenter address of the node
           */
          @JsonProperty("datacenter")
          public String datacenter()
          {
              return datacenter;
          }
  
          /**
           * {@inheritDoc}
           */
          public String toString()
          {
              return "ReplicaMetadata{" +
                     "state='" + state + '\'' +
                     ", status='" + status + '\'' +
                     ", fqdn='" + fqdn + '\'' +
                     ", address='" + address + '\'' +
                     ", port='" + port + '\'' +
                     ", datacenter='" + datacenter + '\'' +
                     '}';
          }
      }
  }
  