package com.sun.launcher.core;

import com.sun.wizards.core.*;
import java.util.*;
import java.io.*;

/**
 * This class is based on the C code found in vold's label_cdrom.c.
 */
public class VolumeID
{
  /*
   * Constants taken from <sys/hsfs_isospec> and <sys/hsfs_spec>
   */
  public static final int ISO_VOLDESC_SEC = 16;
  public static final int ISO_SECTOR_SIZE = 2048;
  public static final int ISO_DESC_TYPE = 0;
  public static final int ISO_VD_EOV = 255;
  public static final int ISO_STD_VER = 6;
  public static final int ISO_STD_ID = 1;
  public static final int ISO_ID_VER = 1;
  public static final int ISO_VD_PVD = 1;
  public static final int ISO_VOL_ID = 40;
  public static final int ISO_VOL_ID_STRLEN = 32;
  public static final int VD_EOV = 255;
  public static final int HS_VOLDESC_SEC = 16;
  public static final int HSV_DESC_TYPE = 8;
  public static final int HSV_STD_ID = 9;
  public static final int HSV_ID_VER = 1;
  public static final int VD_SFS = 1;
  public static final int HSV_STD_VER = 14;
  public static final int HSV_VOL_ID = 48;
  public static final int HSV_VOL_ID_STRLEN = 32;

  public static final String HSV_ID_STRING = "CDROM";
  public static final String CDI_ID_STRING = "CD-I";
  public static final String ISO_ID_STRING = "CD001";

  private static String ddfilename = null;



  public VolumeID(String ddfile)
  {
    this.ddfilename = ddfile;
  }


  public static String hsfsFindName() 
  {
    String volName = null;

    if ((volName=findcdivol()) != null) {
      if (Def.DEBUG) System.out.println ("Found CDI volname "+volName);
    } else if ((volName=findhsvol()) != null) {
      if (Def.DEBUG) System.out.println ("Found CDROM volname "+volName);
    } else if ((volName=findisovol()) != null) {
      if (Def.DEBUG) System.out.println ("Found CD001 volname "+volName);
    }
    return(volName);
  }


  public static String findcdivol()          // CD-I
  {
    if (Def.DEBUG) System.out.println("In findcdivol");
    String volID = null;

    char chars[] = new char[ISO_SECTOR_SIZE];
    byte data[] = getdisk(ISO_VOLDESC_SEC * ISO_SECTOR_SIZE);
    for (int i =0; i<ISO_SECTOR_SIZE; i++) {
       chars[i]=(char)data[i];
    }

    if ((data[ISO_DESC_TYPE]) == ISO_VD_EOV) {
      /* found the end of the vol descriptors */
      if (Def.DEBUG) System.out.println("255 !");

      return(volID);                  /* not found */
    }

    String id=null;
    id = String.valueOf(chars, ISO_STD_ID, CDI_ID_STRING.length());
    if (! id.equals(CDI_ID_STRING)) {
       if (Def.DEBUG) System.out.println("findcdivol want "+CDI_ID_STRING+", have "+id);
       return(volID);          /* not a match */
    }

    if ((data[ISO_STD_VER]) != ISO_ID_VER) {
      if (Def.DEBUG) System.out.println("Not valid sectr continue\n");
      return(volID);                  /* not a match */
    }

    if ((data[ISO_DESC_TYPE]) != ISO_VD_PVD) {
      return(volID);
    }

    volID = String.valueOf(chars,ISO_VOL_ID,ISO_VOL_ID_STRLEN);
    return(volID);
  } 
      

  public static String findhsvol()     //CDROM
  {
    if (Def.DEBUG) System.out.println("In findhsvol");
    String volID = null;

    char chars[] = new char[ISO_SECTOR_SIZE];
    byte data[] = getdisk(HS_VOLDESC_SEC * ISO_SECTOR_SIZE);
    for (int i =0; i<ISO_SECTOR_SIZE; i++) {
       chars[i]=(char)data[i];
    }

    if ((data[HSV_DESC_TYPE]) == VD_EOV) {
      /* found the end of the vol descriptors */
      if (Def.DEBUG) System.out.println("255 !");
      return(volID);                  /* not found */
    }

    String id=null;
    id = String.valueOf(chars, HSV_STD_ID, HSV_ID_STRING.length());
    if (! id.equals(HSV_ID_STRING)) {
       if (Def.DEBUG)System.out.println("findhsvol want "+HSV_ID_STRING+", have "+id);
       return(volID);          /* not a match */
    }

    if ((data[HSV_STD_VER]) != HSV_ID_VER) {
      if (Def.DEBUG)System.out.println("Not valid sectr continue\n");
      return(volID);                  /* not a match */
    }

    if ((data[HSV_DESC_TYPE]) != VD_SFS) {
      return(volID);
    }

    volID = String.valueOf(chars,HSV_VOL_ID,HSV_VOL_ID_STRLEN);
    return(volID);
  } 
      

  public static String findisovol()           //CD001
  {
    if (Def.DEBUG) System.out.println("In findisovol");
    String volID = null;

    char chars[] = new char[ISO_SECTOR_SIZE];
    byte data[] = getdisk(ISO_VOLDESC_SEC * ISO_SECTOR_SIZE);
    for (int i =0; i<ISO_SECTOR_SIZE; i++) {
       chars[i]=(char)data[i];
    }

    if ((data[ISO_DESC_TYPE]) == ISO_VD_EOV) {
      /* found the end of the vol descriptors */
      if (Def.DEBUG)System.out.println("255 !");

      return(volID);                  /* not found */
    }

    String id=null;
    id = String.valueOf(chars, ISO_STD_ID, ISO_ID_STRING.length());
    if (! id.equals(ISO_ID_STRING)) {
       if (Def.DEBUG)System.out.println("findisovol want "+ISO_ID_STRING+", have "+id);
       return(volID);          /* not a match */
    }

    if ((data[ISO_STD_VER]) != ISO_ID_VER) {
      if (Def.DEBUG)System.out.println("Not valid sectr continue!\n");
      return(volID);                  /* not a match */
    }

    if ((data[ISO_DESC_TYPE]) != ISO_VD_PVD) {
      return(volID);
    }

    volID = String.valueOf(chars,ISO_VOL_ID,ISO_VOL_ID_STRLEN);
    return(volID);
  } 
      



  /*
   * Reads one sector of ddfilename, starting at secno
   */
  public static byte[] getdisk(int secno)
  {
    byte buf[] = new byte[ISO_SECTOR_SIZE];

    try {
      if (Def.DEBUG)System.out.println("VolumeID: getdisk secno="+secno);
      File myfile= new File(ddfilename);
      RandomAccessFile raFile = new RandomAccessFile(myfile,"r");
      raFile.seek(secno);
      raFile.read(buf, 0, ISO_SECTOR_SIZE);
      raFile.close();
    } catch (Exception ex) {
      System.out.println(ex);
    }
    return(buf);
  }


  /**
   * Add the runtime class requirements to the specified vector.
   */
  public void addRuntimeResources(Vector resourceVector)
  {
    resourceVector.addElement(new String[] {null, "com.sun.launcher.core.VolumeID"});
  }


}

