/*
 * 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 org.apache.samoa.core.ContentEvent;

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

/**
 * Attribute Content Event represents the instances that split vertically based on their attribute
 * 
 * @author Arinto Murdopo
 * 
 */
public final class AttributeContentEvent implements ContentEvent {

  private static final long serialVersionUID = 6652815649846676832L;

  private final long learningNodeId;
  private final int obsIndex;
  private final double attrVal;
  private final int classVal;
  private final double weight;
  private final transient String key;
  private final boolean isNominal;

  public AttributeContentEvent() {
    learningNodeId = -1;
    obsIndex = -1;
    attrVal = 0.0;
    classVal = -1;
    weight = 0.0;
    key = "";
    isNominal = true;
  }

  private AttributeContentEvent(Builder builder) {
    this.learningNodeId = builder.learningNodeId;
    this.obsIndex = builder.obsIndex;
    this.attrVal = builder.attrVal;
    this.classVal = builder.classVal;
    this.weight = builder.weight;
    this.isNominal = builder.isNominal;
    this.key = builder.key;
  }

  @Override
  public String getKey() {
    return this.key;
  }

  @Override
  public void setKey(String str) {
    // do nothing, maybe useful when we want to reuse the object for
    // serialization/deserialization purpose
  }

  @Override
  public boolean isLastEvent() {
    return false;
  }

  long getLearningNodeId() {
    return this.learningNodeId;
  }

  int getObsIndex() {
    return this.obsIndex;
  }

  int getClassVal() {
    return this.classVal;
  }

  double getAttrVal() {
    return this.attrVal;
  }

  double getWeight() {
    return this.weight;
  }

  boolean isNominal() {
    return this.isNominal;
  }

  static final class Builder {

    // required parameters
    private final long learningNodeId;
    private final int obsIndex;
    private final String key;

    // optional parameters
    private double attrVal = 0.0;
    private int classVal = 0;
    private double weight = 0.0;
    private boolean isNominal = false;

    Builder(long id, int obsIndex, String key) {
      this.learningNodeId = id;
      this.obsIndex = obsIndex;
      this.key = key;
    }

    private Builder(long id, int obsIndex) {
      this.learningNodeId = id;
      this.obsIndex = obsIndex;
      this.key = "";
    }

    Builder attrValue(double val) {
      this.attrVal = val;
      return this;
    }

    Builder classValue(int val) {
      this.classVal = val;
      return this;
    }

    Builder weight(double val) {
      this.weight = val;
      return this;
    }

    Builder isNominal(boolean val) {
      this.isNominal = val;
      return this;
    }

    AttributeContentEvent build() {
      return new AttributeContentEvent(this);
    }
  }

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

    private static double PRECISION = 1000000.0;

    @Override
    public void write(Kryo kryo, Output output, AttributeContentEvent event) {
      output.writeLong(event.learningNodeId, true);
      output.writeInt(event.obsIndex, true);
      output.writeDouble(event.attrVal, PRECISION, true);
      output.writeInt(event.classVal, true);
      output.writeDouble(event.weight, PRECISION, true);
      output.writeBoolean(event.isNominal);
    }

    @Override
    public AttributeContentEvent read(Kryo kryo, Input input,
        Class<AttributeContentEvent> type) {
      AttributeContentEvent ace = new AttributeContentEvent.Builder(input.readLong(true), input.readInt(true))
          .attrValue(input.readDouble(PRECISION, true))
          .classValue(input.readInt(true))
          .weight(input.readDouble(PRECISION, true))
          .isNominal(input.readBoolean())
          .build();
      return ace;
    }
  }

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

    @Override
    public void write(Kryo kryo, Output output, AttributeContentEvent event) {
      output.writeLong(event.learningNodeId, true);
      output.writeInt(event.obsIndex, true);
      output.writeDouble(event.attrVal);
      output.writeInt(event.classVal, true);
      output.writeDouble(event.weight);
      output.writeBoolean(event.isNominal);
    }

    @Override
    public AttributeContentEvent read(Kryo kryo, Input input,
        Class<AttributeContentEvent> type) {
      AttributeContentEvent ace = new AttributeContentEvent.Builder(input.readLong(true), input.readInt(true))
          .attrValue(input.readDouble())
          .classValue(input.readInt(true))
          .weight(input.readDouble())
          .isNominal(input.readBoolean())
          .build();
      return ace;
    }

  }
}
