/**
 * 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.hadoop.hdfs.server.namenode;

import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.apache.hadoop.fs.StorageType;
import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;

/**
 * Aggregate the storage type information for a set of blocks
 *
 */
public class StoragePolicySummary {

  Map<StorageTypeAllocation, Long> storageComboCounts = new HashMap<>();
  final BlockStoragePolicy[] storagePolicies;
  int totalBlocks;

  StoragePolicySummary(BlockStoragePolicy[] storagePolicies) {
    this.storagePolicies = storagePolicies;
  }

  // Add a storage type combination
  void add(StorageType[] storageTypes, BlockStoragePolicy policy) {
    StorageTypeAllocation storageCombo = 
        new StorageTypeAllocation(storageTypes, policy);
    Long count = storageComboCounts.get(storageCombo);
    if (count == null) {
      storageComboCounts.put(storageCombo, 1l);
      storageCombo.setActualStoragePolicy(
          getStoragePolicy(storageCombo.getStorageTypes()));
    } else {
      storageComboCounts.put(storageCombo, count.longValue()+1);
    }
    totalBlocks++;
  }

  // sort the storageType combinations based on the total blocks counts
  // in descending order
  static List<Entry<StorageTypeAllocation, Long>> sortByComparator(
      Map<StorageTypeAllocation, Long> unsortMap) {
    List<Entry<StorageTypeAllocation, Long>> storageAllocations = 
        new LinkedList<>(unsortMap.entrySet());
    // Sorting the list based on values
    Collections.sort(storageAllocations, 
      new Comparator<Entry<StorageTypeAllocation, Long>>() {
          public int compare(Entry<StorageTypeAllocation, Long> o1,
              Entry<StorageTypeAllocation, Long> o2)
          {
            return o2.getValue().compareTo(o1.getValue());
          }
    });
    return storageAllocations;
  }

  public String toString() {
    StringBuilder compliantBlocksSB = new StringBuilder();
    compliantBlocksSB
        .append("\nBlocks satisfying the specified storage policy:")
        .append("\nStorage Policy"
            + "                  # of blocks       % of blocks\n");
    StringBuilder nonCompliantBlocksSB = new StringBuilder();
    Formatter compliantFormatter = new Formatter(compliantBlocksSB);
    Formatter nonCompliantFormatter = new Formatter(nonCompliantBlocksSB);
    NumberFormat percentFormat = NumberFormat.getPercentInstance();
    percentFormat.setMinimumFractionDigits(4);
    percentFormat.setMaximumFractionDigits(4);
    for (Map.Entry<StorageTypeAllocation, Long> storageComboCount:
      sortByComparator(storageComboCounts)) {
      double percent = (double) storageComboCount.getValue() / 
          (double) totalBlocks;
      StorageTypeAllocation sta = storageComboCount.getKey();
      if (sta.policyMatches()) {
        compliantFormatter.format("%-25s %10d  %20s%n",
            sta.getStoragePolicyDescriptor(),
            storageComboCount.getValue(),
            percentFormat.format(percent));
      } else {
        if (nonCompliantBlocksSB.length() == 0) {
          nonCompliantBlocksSB
              .append("\nBlocks NOT satisfying the specified storage policy:")
              .append("\nStorage Policy                  ")
              .append(
              "Specified Storage Policy      # of blocks       % of blocks\n");
        }
        nonCompliantFormatter.format("%-35s %-20s %10d  %20s%n",
            sta.getStoragePolicyDescriptor(),
            sta.getSpecifiedStoragePolicy().getName(),
            storageComboCount.getValue(),
            percentFormat.format(percent));
      }
    }
    if (nonCompliantBlocksSB.length() == 0) {
      nonCompliantBlocksSB.append("\nAll blocks satisfy specified storage policy.\n");
    }
    compliantFormatter.close();
    nonCompliantFormatter.close();
    return compliantBlocksSB.toString() + nonCompliantBlocksSB;
  }

  /**
   * 
   * @param storageTypes - sorted array of storageTypes
   * @return Storage Policy which matches the specific storage Combination
   */
  private BlockStoragePolicy getStoragePolicy(StorageType[] storageTypes) {
    for (BlockStoragePolicy storagePolicy:storagePolicies) {
      StorageType[] policyStorageTypes = storagePolicy.getStorageTypes();
      policyStorageTypes = Arrays.copyOf(policyStorageTypes, policyStorageTypes.length);
      Arrays.sort(policyStorageTypes);
      if (policyStorageTypes.length <= storageTypes.length) {
        int i = 0; 
        for (; i < policyStorageTypes.length; i++) {
          if (policyStorageTypes[i] != storageTypes[i]) {
            break;
          }
        }
        if (i < policyStorageTypes.length) {
          continue;
        }
        int j=policyStorageTypes.length;
        for (; j < storageTypes.length; j++) {
          if (policyStorageTypes[i-1] != storageTypes[j]) {
            break;
          }
        }

        if (j==storageTypes.length) {
          return storagePolicy;
        }
      }
    }
    return null;
  }

  /**
   * Internal class which represents a unique Storage type combination
   *
   */
  static class StorageTypeAllocation {
    private final BlockStoragePolicy specifiedStoragePolicy;
    private final StorageType[] storageTypes;
    private BlockStoragePolicy actualStoragePolicy;

    StorageTypeAllocation(StorageType[] storageTypes, 
        BlockStoragePolicy specifiedStoragePolicy) {
      Arrays.sort(storageTypes);
      this.storageTypes = storageTypes;
      this.specifiedStoragePolicy = specifiedStoragePolicy;
    }
    
    StorageType[] getStorageTypes() {
      return storageTypes;
    }

    BlockStoragePolicy getSpecifiedStoragePolicy() {
      return specifiedStoragePolicy;
    }
    
    void setActualStoragePolicy(BlockStoragePolicy actualStoragePolicy) {
      this.actualStoragePolicy = actualStoragePolicy;
    }
    
    BlockStoragePolicy getActualStoragePolicy() {
      return actualStoragePolicy;
    }

    private static String getStorageAllocationAsString
      (Map<StorageType, Integer> storageType_countmap) {
      StringBuilder sb = new StringBuilder();
      for (Map.Entry<StorageType, Integer> 
      storageTypeCountEntry:storageType_countmap.entrySet()) {
        sb.append(storageTypeCountEntry.getKey().name()+ ":"
            + storageTypeCountEntry.getValue() + ",");
      }
      if (sb.length() > 1) {
        sb.deleteCharAt(sb.length()-1);
      }
      return sb.toString();
    }

    private String getStorageAllocationAsString() {
      Map<StorageType, Integer> storageType_countmap = 
          new EnumMap<>(StorageType.class);
      for (StorageType storageType: storageTypes) {
        Integer count = storageType_countmap.get(storageType);
        if (count == null) {
          storageType_countmap.put(storageType, 1);
        } else {
          storageType_countmap.put(storageType, count.intValue()+1);
        }
      }
      return (getStorageAllocationAsString(storageType_countmap));
    }
    
    String getStoragePolicyDescriptor() {
      StringBuilder storagePolicyDescriptorSB = new StringBuilder();
      if (actualStoragePolicy!=null) {
        storagePolicyDescriptorSB.append(getStorageAllocationAsString())
        .append("(")
        .append(actualStoragePolicy.getName())
        .append(")");
      } else {
        storagePolicyDescriptorSB.append(getStorageAllocationAsString());
      }
      return storagePolicyDescriptorSB.toString();
    }
    
    boolean policyMatches() {
      return specifiedStoragePolicy.equals(actualStoragePolicy);
    }
    
    @Override
    public String toString() {
      return specifiedStoragePolicy.getName() + "|" + getStoragePolicyDescriptor();
    }

    @Override
    public int hashCode() {
      return Objects.hash(specifiedStoragePolicy,Arrays.hashCode(storageTypes));
    }

    @Override
    public boolean equals(Object another) {
      return (another instanceof StorageTypeAllocation && 
          Objects.equals(specifiedStoragePolicy,
              ((StorageTypeAllocation)another).specifiedStoragePolicy) &&
              Arrays.equals(storageTypes,
                  ((StorageTypeAllocation)another).storageTypes));
    }
  }
}
