/*
** Module   : StatusCounter.java
** Abstract : records a number of matches by status code
**
** Copyright (c) 2009-2022, Golden Code Development Corporation.
**
** -#- -I- --Date-- -----------------------Description------------------------
** 001 GES 20090213 Records a number of matches by status code.
**     TJD 20220803 Updated for Java 11
*/

/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.goldencode.harness;

import java.util.*;

/**
 * Records a number of matches by status code.
 */
public class StatusCounter
{
   /** Store the matches keyed by status code. */
   private Map<Status, Integer> matches =
      new EnumMap<Status, Integer>(Status.class);
      
   /** Descriptive text for the statistic. */ 
   private String descr = "";
   
   /**
    * Default constructor.
    */
   public StatusCounter()
   {
   }
   
   /**
    * Copy constructor.
    *
    * @param    copy
    *           The instance upon which to pattern the duplicate.
    */
   public StatusCounter(StatusCounter copy)
   {
      this.matches = new EnumMap<Status, Integer>(Status.class);
      this.descr   = copy.descr;
      
      this.matches.putAll(copy.matches);
   }
   
   /**
    * Calculate the status frequency distribution for the given reports.
    *
    * @param    list
    *           List of report elements.
    */
   public void calculate(List<? extends Reportable> list)
   {
      Iterator<? extends Reportable> iter = list.iterator();
      
      while (iter.hasNext())
      {
         Reportable report = iter.next();
         Status     next   = report.getStatus();
         
         Integer value = matches.get(next);
         
         if (value == null)
         {
            value = Integer.valueOf(1);
         }
         else
         {
            value = Integer.valueOf(value.intValue() + 1);
         }
         
         matches.put(next, value);
      }
   }
   
   /**
    * Accumulate the given counter values as additions to the current
    * instance's counters.
    *
    * @param    counter
    *           The values to add to this instance's counters.
    */
   public void accumulate(StatusCounter counter)
   {
      Status[] keys = Status.values();
      
      for (int i = 0; i < keys.length; i++)
      {
         int value = getCounter(keys[i]) + counter.getCounter(keys[i]);
         setCounter(keys[i], value);
      }
   }
   
   /**
    * Get the counter associated with the given status.
    *
    * @param    status
    *           Status code to check.
    *
    * @return   Number of matches recorded for that status code.
    */
   public int getCounter(Status status)
   {
      Integer value = matches.get(status);
      return (value == null) ? 0 : value.intValue();
   }
   
   /**
    * Set the counter associated with the given status.
    *
    * @param    status
    *           Status code to check.
    * @param    value
    *           Number of matches recorded for that status code.
    */
   public void setCounter(Status status, int value)
   {
      matches.put(status, value);
   }
   
   /**
    * Get the verbose description of the statistic.
    *
    * @return   A description of the statistic.
    */
   public String getDescription()
   {
      return descr;
   }
   
   /**
    * Set the verbose description of the statistic.
    *
    * @param    descr
    *           A description of the statistic.
    */
   public void setDescription(String descr)
   {
      this.descr = (descr == null) ? "" : descr;
   }
}
