/*
 * 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.geode.internal.cache.partitioned.rebalance.model;

import java.util.Set;
import java.util.TreeSet;

import org.apache.logging.log4j.Logger;

import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Represents a single member of the distributed system.
 */
public class Member implements Comparable<Member> {
  private static final Logger logger = LogService.getLogger();

  private final AddressComparor addressComparor;
  private final InternalDistributedMember memberId;
  protected float weight;
  private float totalLoad;
  private float totalPrimaryLoad;
  private long totalBytes;
  private long localMaxMemory;
  private final Set<Bucket> buckets = new TreeSet<>();
  private final Set<Bucket> primaryBuckets = new TreeSet<>();
  private final boolean isCritical;
  private final boolean enforceLocalMaxMemory;

  Member(AddressComparor addressComparor, InternalDistributedMember memberId, boolean isCritical,
      boolean enforceLocalMaxMemory) {
    this.addressComparor = addressComparor;
    this.memberId = memberId;
    this.isCritical = isCritical;
    this.enforceLocalMaxMemory = enforceLocalMaxMemory;
  }

  Member(AddressComparor addressComparor, InternalDistributedMember memberId, float weight,
      long localMaxMemory, boolean isCritical, boolean enforceLocalMaxMemory) {
    this(addressComparor, memberId, isCritical, enforceLocalMaxMemory);
    this.weight = weight;
    this.localMaxMemory = localMaxMemory;
  }

  /**
   * @param sourceMember the member we will be moving this bucket off of
   * @param checkZone true if we should not put two copies of a bucket on two nodes with the same
   *        IP address.
   */
  public RefusalReason willAcceptBucket(Bucket bucket, Member sourceMember, boolean checkZone) {
    // make sure this member is not already hosting this bucket
    if (getBuckets().contains(bucket)) {
      return RefusalReason.ALREADY_HOSTING;
    }
    // Check the ip address
    if (checkZone) {
      // If the source member is equivalent to the target member, go
      // ahead and allow the bucket move (it's not making our redundancy worse).
      // TODO we could have some logic to prefer moving to different ip addresses
      // Probably that logic should be another stage after redundancy recovery, like
      // improveRedundancy.
      boolean sourceIsEquivalent = sourceMember != null
          && addressComparor.areSameZone(getMemberId(), sourceMember.getDistributedMember());
      if (sourceMember == null || !sourceIsEquivalent) {
        for (Member hostingMember : bucket.getMembersHosting()) {
          if ((!hostingMember.equals(sourceMember) || addressComparor.enforceUniqueZones())
              && addressComparor.areSameZone(getMemberId(), hostingMember.getDistributedMember())) {
            if (logger.isDebugEnabled()) {
              logger.debug(
                  "Member {} would prefer not to host {} because it is already on another member with the same redundancy zone",
                  this, bucket);
            }
            return RefusalReason.SAME_ZONE;
          }
        }
      }
    }

    // check the localMaxMemory
    if (this.enforceLocalMaxMemory && this.totalBytes + bucket.getBytes() > this.localMaxMemory) {
      if (logger.isDebugEnabled()) {
        logger.debug("Member {} won't host bucket {} because it doesn't have enough space", this,
            bucket);
      }
      return RefusalReason.LOCAL_MAX_MEMORY_FULL;
    }

    // check to see if the heap is critical
    if (isCritical) {
      if (logger.isDebugEnabled()) {
        logger.debug("Member {} won't host bucket {} because it's heap is critical", this, bucket);
      }
      return RefusalReason.CRITICAL_HEAP;
    }

    return RefusalReason.NONE;
  }

  public boolean addBucket(Bucket bucket) {
    if (getBuckets().add(bucket)) {
      bucket.addMember(this);
      this.totalBytes += bucket.getBytes();
      this.totalLoad += bucket.getLoad();
      return true;
    }
    return false;
  }

  public boolean removeBucket(Bucket bucket) {
    if (getBuckets().remove(bucket)) {
      bucket.removeMember(this);
      this.totalBytes -= bucket.getBytes();
      this.totalLoad -= bucket.getLoad();
      return true;
    }
    return false;
  }

  public boolean removePrimary(Bucket bucket) {
    if (getPrimaryBuckets().remove(bucket)) {
      this.totalPrimaryLoad -= bucket.getPrimaryLoad();
      return true;
    }
    return false;
  }

  public boolean addPrimary(Bucket bucket) {
    if (getPrimaryBuckets().add(bucket)) {
      this.totalPrimaryLoad += bucket.getPrimaryLoad();
      return true;
    }
    return false;
  }

  public int getBucketCount() {
    return getBuckets().size();
  }

  public long getConfiguredMaxMemory() {
    return this.localMaxMemory;
  }

  public InternalDistributedMember getDistributedMember() {
    return getMemberId();
  }

  public int getPrimaryCount() {
    int primaryCount = 0;
    for (Bucket bucket : getBuckets()) {
      if (this.equals(bucket.getPrimary())) {
        primaryCount++;
      }
    }
    return primaryCount;
  }

  public long getSize() {
    return this.totalBytes;
  }

  public float getTotalLoad() {
    return this.totalLoad;
  }

  public float getWeight() {
    return this.weight;
  }

  @Override
  public String toString() {
    return "Member(id=" + getMemberId() + ")";
  }

  public float getPrimaryLoad() {
    return this.totalPrimaryLoad;
  }

  public Set<Bucket> getBuckets() {
    return this.buckets;
  }

  InternalDistributedMember getMemberId() {
    return this.memberId;
  }

  Set<Bucket> getPrimaryBuckets() {
    return this.primaryBuckets;
  }

  void changeLocalMaxMemory(long change) {
    localMaxMemory += change;
  }

  void changeTotalLoad(float change) {
    totalLoad += change;
  }

  void changePrimaryLoad(float change) {
    totalPrimaryLoad += change;
  }

  void changeTotalBytes(float change) {
    totalBytes += (long) Math.round(change);
  }

  @Override
  public int hashCode() {
    return memberId.hashCode();
  }

  @Override
  public boolean equals(Object other) {
    if (!(other instanceof Member)) {
      return false;
    }
    Member o = (Member) other;
    return this.memberId.equals(o.memberId);
  }

  @Override
  public int compareTo(Member other) {
    // memberId is InternalDistributedMember which implements Comparable
    return this.memberId.compareTo(other.memberId);
  }
}
