/**
 * Finds free and appropriate file storage (Target)
 */

package org.bucksch.zeipis.core;
import org.bucksch.zeipis.all.*;
import org.bucksch.zeipis.store.*;
import org.bucksch.zeipis.recorder.ScheduledRecording;
import java.util.*;

public class StorageAllocator
{
  static public Store findStorage(PlannedRecording recording)
    throws NoFreeSpace, Exception
  {
    // Sort stores by whether they are on same host as recording device
    Vector<Store> stores = Util.newVector();
    stores.addAll(CoreData.me.myStores.values());
    final String wantedHost = recording.device().host();
    stores = Util.sort(stores, new Comparator<Store>() {
      public int compare(Store o1, Store o2)
      {
        // -1: o1 < o2,  0: o1 == o2, +1: o1 > o2
        if (o1.host().equals(o2.host()))
          return 0;
        if (o1.host().equals(wantedHost))
          return -1;
        if (o2.host().equals(wantedHost))
          return 1;
        return 0;
      }});

    // Check whether store has enough free space left
    Store chosenStore = null;
    for (Store store : stores)
    {
      if(!hasEnoughSpace(store, recording))
        continue;
      chosenStore = store;
      break;
    }
    if (chosenStore == null)
    {
      throw new NoFreeSpace("Not enough free space on " + chosenStore);
      // TODO delete old unwanted stuff
    }

    return chosenStore;
  }
  static public boolean hasEnoughSpace(Store store, ScheduledRecording recording)
  {
    long freeSpace = store.freeSpace();
    Util.debug("free space " + (freeSpace / 1048000) + " MB");
    long lengthInSeconds = (recording.endtime().getTime() - recording.starttime().getTime()) / 1000;
    long estimatedBytes = estimatedBytesPerSecond * lengthInSeconds;
    return estimatedBytes < freeSpace - leaveFreeBytes;
  }

  // Config TODO configurable
  static final protected long estimatedBytesPerSecond = 400000; // about 1.4GB/h
  static final protected long leaveFreeBytes = 400000;
}

class NoFreeSpace extends Exception
{
  public NoFreeSpace(String message)
  {
    super(message);
  }
  private static final long serialVersionUID = 6077564272453232034L;
}
