/*
 * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.loader.csv;

import java.lang.invoke.MethodHandles;
import java.time.LocalDate;

import org.joda.beans.ImmutableBean;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaBean;
import org.joda.beans.TypedMetaBean;
import org.joda.beans.gen.BeanDefinition;
import org.joda.beans.gen.PropertyDefinition;
import org.joda.beans.impl.light.LightMetaBean;

import com.google.common.collect.ComparisonChain;

/**
 * Represents a node on a calibrated curve.
 */
@BeanDefinition(style = "light")
final class LoadedCurveNode
    implements Comparable<LoadedCurveNode>, ImmutableBean {

  /**
   * The date that the curve node value applies to.
   */
  @PropertyDefinition(validate = "notNull")
  private final LocalDate date;
  /**
   * The value of the curve at the node.
   */
  @PropertyDefinition
  private final double value;
  /**
   * The label to use for the node.
   */
  @PropertyDefinition(validate = "notNull")
  private final String label;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance.
   * 
   * @param date  the date of the node
   * @param value  the value of the node
   * @param label  the label of the node
   * @return the curve node
   */
  static LoadedCurveNode of(LocalDate date, double value, String label) {
    return new LoadedCurveNode(date, value, label);
  }

  //-------------------------------------------------------------------------
  /**
   * Compares this node to another by date.
   * 
   * @param other  the other curve node
   * @return negative if this node is earlier, positive if later and zero if equal
   */
  @Override
  public int compareTo(LoadedCurveNode other) {
    return ComparisonChain.start()
        .compare(getDate(), other.getDate())
        .compare(getValue(), other.getValue())
        .compare(getLabel(), other.getLabel())
        .result();
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code LoadedCurveNode}.
   */
  private static final TypedMetaBean<LoadedCurveNode> META_BEAN =
      LightMetaBean.of(
          LoadedCurveNode.class,
          MethodHandles.lookup(),
          new String[] {
              "date",
              "value",
              "label"},
          new Object[0]);

  /**
   * The meta-bean for {@code LoadedCurveNode}.
   * @return the meta-bean, not null
   */
  public static TypedMetaBean<LoadedCurveNode> meta() {
    return META_BEAN;
  }

  static {
    MetaBean.register(META_BEAN);
  }

  private LoadedCurveNode(
      LocalDate date,
      double value,
      String label) {
    JodaBeanUtils.notNull(date, "date");
    JodaBeanUtils.notNull(label, "label");
    this.date = date;
    this.value = value;
    this.label = label;
  }

  @Override
  public TypedMetaBean<LoadedCurveNode> metaBean() {
    return META_BEAN;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the date that the curve node value applies to.
   * @return the value of the property, not null
   */
  public LocalDate getDate() {
    return date;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the value of the curve at the node.
   * @return the value of the property
   */
  public double getValue() {
    return value;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the label to use for the node.
   * @return the value of the property, not null
   */
  public String getLabel() {
    return label;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      LoadedCurveNode other = (LoadedCurveNode) obj;
      return JodaBeanUtils.equal(date, other.date) &&
          JodaBeanUtils.equal(value, other.value) &&
          JodaBeanUtils.equal(label, other.label);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(date);
    hash = hash * 31 + JodaBeanUtils.hashCode(value);
    hash = hash * 31 + JodaBeanUtils.hashCode(label);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(128);
    buf.append("LoadedCurveNode{");
    buf.append("date").append('=').append(JodaBeanUtils.toString(date)).append(',').append(' ');
    buf.append("value").append('=').append(JodaBeanUtils.toString(value)).append(',').append(' ');
    buf.append("label").append('=').append(JodaBeanUtils.toString(label));
    buf.append('}');
    return buf.toString();
  }

  //-------------------------- AUTOGENERATED END --------------------------
}
