/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.apache.samoa.instances;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * Licensed 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.
 * #L%
 */

import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.io.InputStream;

/**
 * 
 * @author abifet
 */
public class Instances implements Serializable {

  public static final String ARFF_RELATION = "@relation";
  public static final String ARFF_DATA = "@data";

  protected InstanceInformation instanceInformation;
  /**
   * The instances.
   */
  protected List<Instance> instances;

  transient protected Loader loader;

  protected static enum AVRO_ENCODING_FORMAT {
    JSON, BINARY
  }

  protected int classAttribute;

  public Instances(InstancesHeader modelContext) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  public Instances(Instances chunk) {
    this.instanceInformation = chunk.instanceInformation();
    // this.relationName = chunk.relationName;
    // this.attributes = chunk.attributes;
    this.instances = chunk.instances;
  }

  public Instances() {
    // this.instanceInformation = chunk.instanceInformation();
    // this.relationName = chunk.relationName;
    // this.attributes = chunk.attributes;
    // this.instances = chunk.instances;
  }

  public Instances(Reader reader, int size, int classAttribute) {
    this.classAttribute = classAttribute;
    loader = new ArffLoader(reader, 0, classAttribute);
    this.instanceInformation = loader.getStructure();
    this.instances = new ArrayList<>();
  }

  public Instances(InputStream inputStream, int classAttribute, String encodingFormat) {
    this.classAttribute = classAttribute;

    if (encodingFormat.equalsIgnoreCase(AVRO_ENCODING_FORMAT.BINARY.toString()))
      loader = new AvroBinaryLoader(inputStream, classAttribute);
    else
      loader = new AvroJsonLoader(inputStream, classAttribute);

    this.instanceInformation = loader.getStructure();
    this.instances = new ArrayList<>();
  }

  public Instances(Instances chunk, int capacity) {
    this(chunk);
  }

  public Instances(String st, List<Attribute> v, int capacity) {

    this.instanceInformation = new InstanceInformation(st, v);
    this.instances = new ArrayList<>();
  }

  public Instances(Instances chunk, int i, int j) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  public Instances(StringReader st, int v) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  // Information Instances
  public void setRelationName(String string) {
    this.instanceInformation.setRelationName(string);
  }

  public String getRelationName() {
    return this.instanceInformation.getRelationName();
  }

  public int classIndex() {
    return this.instanceInformation.classIndex();
  }

  public void setClassIndex(int classIndex) {
    this.instanceInformation.setClassIndex(classIndex);
  }

  public Attribute classAttribute() {
    return this.instanceInformation.classAttribute();
  }

  public int numAttributes() {
    return this.instanceInformation.numAttributes();
  }

  public Attribute attribute(int w) {
    return this.instanceInformation.attribute(w);
  }

  public int numClasses() {
    return this.instanceInformation.numClasses();
  }

  public void deleteAttributeAt(Integer integer) {
    this.instanceInformation.deleteAttributeAt(integer);
  }

  public void insertAttributeAt(Attribute attribute, int i) {
    this.instanceInformation.insertAttributeAt(attribute, i);
  }

  // List of Instances
  public Instance instance(int num) {
    return this.instances.get(num);
  }

  public int numInstances() {
    return this.instances.size();
  }

  public void add(Instance inst) {
    this.instances.add(inst.copy());
  }

  public void randomize(Random random) {
    for (int j = numInstances() - 1; j > 0; j--) {
      swap(j, random.nextInt(j + 1));
    }
  }

  public void stratify(int numFolds) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  public Instances trainCV(int numFolds, int n, Random random) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  public Instances testCV(int numFolds, int n) {
    throw new UnsupportedOperationException("Not yet implemented");
  }

  /*
   * public Instances dataset() { throw new
   * UnsupportedOperationException("Not yet implemented"); }
   */
  public double meanOrMode(int j) {
    throw new UnsupportedOperationException("Not yet implemented"); // CobWeb
  }

  public boolean readInstance(Reader fileReader) {

    if (loader == null) {
      loader = new ArffLoader(fileReader, 0, this.classAttribute);
    }
    return readInstance();
  }

  public boolean readInstance() {

    Instance inst = loader.readInstance();
    if (inst != null) {
      inst.setDataset(this);
      add(inst);
      return true;
    } else {
      return false;
    }
  }

  public void delete() {
    this.instances = new ArrayList<>();
  }

  public void swap(int i, int j) {
    Instance in = instances.get(i);
    instances.set(i, instances.get(j));
    instances.set(j, in);
  }

  private InstanceInformation instanceInformation() {
    return this.instanceInformation;
  }

  public Attribute attribute(String name) {

    for (int i = 0; i < numAttributes(); i++) {
      if (attribute(i).name().equals(name)) {
        return attribute(i);
      }
    }
    return null;
  }

  @Override
  public String toString() {
    StringBuilder text = new StringBuilder();

    for (int i = 0; i < numInstances(); i++) {
      text.append(instance(i).toString());
      if (i < numInstances() - 1) {
        text.append('\n');
      }
    }
    return text.toString();
  }

  // toString() with header
  public String toStringArff() {
    StringBuilder text = new StringBuilder();

    text.append(ARFF_RELATION).append(" ")
        .append(Utils.quote(getRelationName())).append("\n\n");
    for (int i = 0; i < numAttributes(); i++) {
      text.append(attribute(i).toString()).append("\n");
    }
    text.append("\n").append(ARFF_DATA).append("\n");

    text.append(toString());
    return text.toString();

  }
}
