/*
 * 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.samoa.learners.classifiers.ensemble;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.samoa.core.ContentEvent;
import org.apache.samoa.instances.Instance;
import org.apache.samoa.learners.InstanceContentEvent;
import org.apache.samoa.learners.ResultContentEvent;
import org.apache.samoa.moa.core.DoubleVector;
import org.apache.samoa.moa.core.Utils;
import org.apache.samoa.topology.Stream;

/**
 * The Class BoostingPredictionCombinerProcessor.
 */
public class BoostingPredictionCombinerProcessor extends PredictionCombinerProcessor {

  private static final long serialVersionUID = -1606045723451191232L;

  // Weigths classifier
  protected double[] scms;

  // Weights instance
  protected double[] swms;

  /**
   * On event.
   * 
   * @param event
   *          the event
   * @return true, if successful
   */
  @Override
  public boolean process(ContentEvent event) {

    ResultContentEvent inEvent = (ResultContentEvent) event;
    double[] prediction = inEvent.getClassVotes();
    int instanceIndex = (int) inEvent.getInstanceIndex();

    addStatisticsForInstanceReceived(instanceIndex, inEvent.getClassifierIndex(), prediction, 1);
    // Boosting
    addPredictions(instanceIndex, inEvent, prediction);

    if (inEvent.isLastEvent() || hasAllVotesArrivedInstance(instanceIndex)) {
      DoubleVector combinedVote = this.mapVotesforInstanceReceived.get(instanceIndex);
      if (combinedVote == null) {
        combinedVote = new DoubleVector();
      }
      ResultContentEvent outContentEvent = new ResultContentEvent(inEvent.getInstanceIndex(),
          inEvent.getInstance(), inEvent.getClassId(),
          combinedVote.getArrayCopy(), inEvent.isLastEvent(), inEvent.getArrivalTimestamp());
      outContentEvent.setEvaluationIndex(inEvent.getEvaluationIndex());
      outputStream.put(outContentEvent);
      clearStatisticsInstance(instanceIndex);
      // Boosting
      computeBoosting(inEvent, instanceIndex);
      return true;
    }
    return false;

  }

  protected Random random;

  protected int trainingWeightSeenByModel;

  @Override
  protected double getEnsembleMemberWeight(int i) {
    double em = this.swms[i] / (this.scms[i] + this.swms[i]);
    if ((em == 0.0) || (em > 0.5)) {
      return 0.0;
    }
    double Bm = em / (1.0 - em);
    return Math.log(1.0 / Bm);
  }

  @Override
  public void reset() {
    this.random = new Random();
    this.trainingWeightSeenByModel = 0;
    this.scms = new double[this.ensembleSize];
    this.swms = new double[this.ensembleSize];
  }

  private boolean correctlyClassifies(int i, Instance inst, int instanceIndex) {
    int predictedClass = (int) mapPredictions.get(instanceIndex).getValue(i);
    return predictedClass == (int) inst.classValue();
  }

  protected Map<Integer, DoubleVector> mapPredictions;

  private void addPredictions(int instanceIndex, ResultContentEvent inEvent, double[] prediction) {
    if (this.mapPredictions == null) {
      this.mapPredictions = new HashMap<>();
    }
    DoubleVector predictions = this.mapPredictions.get(instanceIndex);
    if (predictions == null) {
      predictions = new DoubleVector();
    }
    predictions.setValue(inEvent.getClassifierIndex(), Utils.maxIndex(prediction));
    this.mapPredictions.put(instanceIndex, predictions);
  }

  private void computeBoosting(ResultContentEvent inEvent, int instanceIndex) {
    // Starts code for Boosting
    // Send instances to train
    double lambda_d = 1.0;
    for (int i = 0; i < this.ensembleSize; i++) {
      double k = lambda_d;
      Instance inst = inEvent.getInstance();
      if (k > 0.0) {
        Instance weightedInst = inst.copy();
        weightedInst.setWeight(inst.weight() * k);
        // this.ensemble[i].trainOnInstance(weightedInst);
        InstanceContentEvent instanceContentEvent = new InstanceContentEvent(
            inEvent.getInstanceIndex(), weightedInst, true, false);
        instanceContentEvent.setClassifierIndex(i);
        instanceContentEvent.setEvaluationIndex(inEvent.getEvaluationIndex());
        trainingStream.put(instanceContentEvent);
      }
      if (this.correctlyClassifies(i, inst, instanceIndex)) {
        this.scms[i] += lambda_d;
        lambda_d *= this.trainingWeightSeenByModel / (2 * this.scms[i]);
      } else {
        this.swms[i] += lambda_d;
        lambda_d *= this.trainingWeightSeenByModel / (2 * this.swms[i]);
      }
    }
  }

  /**
   * Gets the training stream.
   * 
   * @return the training stream
   */
  public Stream getTrainingStream() {
    return trainingStream;
  }

  /**
   * Sets the training stream.
   * 
   * @param trainingStream
   *          the new training stream
   */
  public void setTrainingStream(Stream trainingStream) {
    this.trainingStream = trainingStream;
  }

  /** The training stream. */
  private Stream trainingStream;

}
