package ucar.nc2.iosp.grib;

import ucar.grib.Index;
import ucar.grib.NoValidGribException;
import ucar.grib.NotSupportedException;
import ucar.grib.grib2.*;

import ucar.nc2.*;
import ucar.nc2.util.CancelTask;

import ucar.unidata.io.RandomAccessFile;

import java.io.*;
import java.util.*;

/**
 * Grib2 iosp.
 */
public class Grib2ServiceProvider extends GribServiceProvider {

  private Grib2Data dataReader;

  public boolean isValidFile(RandomAccessFile raf) {

    try {
      raf.seek(0);
      raf.order( RandomAccessFile.BIG_ENDIAN );

      Grib2Input g2i = new Grib2Input( raf );
      int edition = g2i.getEdition();
      return edition == 2;

    } catch (Exception e) {
      return false;
    }
  }

  public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) throws IOException {
    this.raf = raf;
    raf.seek(0);
    raf.order( RandomAccessFile.BIG_ENDIAN );    

    long startTime = System.currentTimeMillis();
    if (GribServiceProvider.debugOpen) System.out.println("GribServiceProvider open = "+ncfile.getLocation());

    Grib2Record firstRecord = null;
    try {
      Grib2Input g2i = new Grib2Input( raf );

      long start2 = System.currentTimeMillis();
      // params getData, getProducts (implies  unique GDSs too), oneRecord
      // open it up and get the first product
      g2i.scan( false, false, true );

      ArrayList records = g2i.getRecords();
      firstRecord = (Grib2Record) records.get(0);
      if (debugTiming) {
        long took = System.currentTimeMillis() - start2;
        System.out.println("  read one record took="+took+" msec ");
      }

   } catch (NoValidGribException noGrib) {
      System.err.println("NoValidGribException : " + noGrib);
    } catch (NotSupportedException noSupport) {
      System.err.println("NotSupportedException : " + noSupport);
    }

    // get an Index, done in the superclass
    Index index = getIndex(2, ncfile.getLocation(), raf, cancelTask);

    Grib2Lookup lookup = new Grib2Lookup( firstRecord );

    // make it into netcdf objects
    Index2NC delegate = new Index2NC();
    delegate.open( index, lookup, 2, ncfile, cancelTask);

    ncfile.finish();

    try {
      dataReader = new Grib2Data( raf );
    } catch (NotSupportedException e) {
      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    } catch (NoValidGribException e) {
      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    }

    if (debugTiming) {
      long took = System.currentTimeMillis() - startTime;
      System.out.println(" open "+ncfile.getLocation()+" took="+took+" msec ");
    }
  }


  /////////////////////////////////////////////////////////////////////////////////////////////////

  protected float[] _readData( long GdsOffset, long PdsOffset, int decimalScale, boolean bmsExists) throws IOException {
    try {
      return dataReader.getData( GdsOffset, PdsOffset );
    } catch (NotSupportedException e) {
      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    } catch (NoValidGribException e) {
      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    }
    return null;
  }

}
