/*
 * 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.trees;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/**
 * Compute content event is the message that is sent by Model Aggregator Processor to request Local Statistic PI to
 * start the local statistic calculation for splitting
 * 
 * @author Arinto Murdopo
 * 
 */
public final class ComputeContentEvent extends ControlContentEvent {

  private static final long serialVersionUID = 5590798490073395190L;

  private final double[] preSplitDist;
  private final long splitId;
  
  private int ensembleId; //the id of the ensemble that send the event

  public ComputeContentEvent() {
    super(-1);
    preSplitDist = null;
    splitId = -1;
  }

  ComputeContentEvent(long splitId, long id, double[] preSplitDist) {
    super(id);
    // this.preSplitDist = Arrays.copyOf(preSplitDist, preSplitDist.length);
    this.preSplitDist = preSplitDist;
    this.splitId = splitId;
  }

  @Override
  LocStatControl getType() {
    return LocStatControl.COMPUTE;
  }

  double[] getPreSplitDist() {
    return this.preSplitDist;
  }

  long getSplitId() {
    return this.splitId;
  }

  /**
   * The Kryo serializer class for ComputeContentEevent when executing on top of Storm. This class allow us to change
   * the precision of the statistics.
   * 
   * @author Arinto Murdopo
   * 
   */
  public static final class ComputeCESerializer extends Serializer<ComputeContentEvent> {

    private static double PRECISION = 1000000.0;

    @Override
    public void write(Kryo kryo, Output output, ComputeContentEvent object) {
      output.writeLong(object.splitId, true);
      output.writeLong(object.learningNodeId, true);

      output.writeInt(object.preSplitDist.length, true);
      for (int i = 0; i < object.preSplitDist.length; i++) {
        output.writeDouble(object.preSplitDist[i], PRECISION, true);
      }
    }

    @Override
    public ComputeContentEvent read(Kryo kryo, Input input,
        Class<ComputeContentEvent> type) {
      long splitId = input.readLong(true);
      long learningNodeId = input.readLong(true);

      int dataLength = input.readInt(true);
      double[] preSplitDist = new double[dataLength];

      for (int i = 0; i < dataLength; i++) {
        preSplitDist[i] = input.readDouble(PRECISION, true);
      }

      return new ComputeContentEvent(splitId, learningNodeId, preSplitDist);
    }
  }

  /**
   * The Kryo serializer class for ComputeContentEevent when executing on top of Storm with full precision of the
   * statistics.
   * 
   * @author Arinto Murdopo
   * 
   */
  public static final class ComputeCEFullPrecSerializer extends Serializer<ComputeContentEvent> {

    @Override
    public void write(Kryo kryo, Output output, ComputeContentEvent object) {
      output.writeLong(object.splitId, true);
      output.writeLong(object.learningNodeId, true);

      output.writeInt(object.preSplitDist.length, true);
      for (int i = 0; i < object.preSplitDist.length; i++) {
        output.writeDouble(object.preSplitDist[i]);
      }
    }

    @Override
    public ComputeContentEvent read(Kryo kryo, Input input,
        Class<ComputeContentEvent> type) {
      long splitId = input.readLong(true);
      long learningNodeId = input.readLong(true);

      int dataLength = input.readInt(true);
      double[] preSplitDist = new double[dataLength];

      for (int i = 0; i < dataLength; i++) {
        preSplitDist[i] = input.readDouble();
      }

      return new ComputeContentEvent(splitId, learningNodeId, preSplitDist);
    }

  }

  public int getEnsembleId() {
    return ensembleId;
  }
  
  public void setEnsembleId(int ensembleId) {
    this.ensembleId = ensembleId;
  }
}
