//-*-c++-*--------------------------------------------------------------
//  volPrint.cpp
//   Exercises all but the Extended Attributes classes. Reads in and
//   prints out volume structures, root directory, and/or free space
//   information.
//
//      Unpublished Confidential Information of Hewlett-Packard
//      Company. Do not disclose.  Copyright (c) Hewlett-Packard
//      Company 1996. All rights reserved
// 
// The contents of this software are proprietary and confidential to
// the Hewlett- Packard Company, and are limited in distribution to
// those with a direct need to know.  Individuals having access to
// this software are responsible for maintaining the confidentiality
// of the content and for keeping the software secure when not in use.
// Transfer to any party is strictly forbidden other than as expressly
// permitted in writing by Hewlett-Packard Company.  Unauthorized
// transfer to or possession by any unauthorized party may be a
// criminal offense.
//
//                  RESTRICTED RIGHTS LEGEND
//
//      Use,  duplication,  or disclosure by the U. S. Government is
//      subject to restrictions as set forth in subparagraph (c) (1)
//      (ii) in the Rights in Technical Data and Computer Software
//      clause in DFARS 252.227-7013 or any other successor clause.
//
//                      HEWLETT-PACKARD COMPANY
//                      3000 Hanover St.
//                      Palo Alto, CA  94304 U.S.A.
//
//      Rights for non-DOD U.S. Government Departments and Agencies
//      are as set forth in FAR 52.227-19 (c) (1,2) or any other
//      successor clause.
//  
// For USAGE, see printf() statements in the source code below
//
//----------------------------------------------------------------------
//
// $Source: /projects/HMS/nsr/udfAncil/ssTest/volPrint.cpp,v $
// $Revision: 1.21 $    $Author: hmgr $
// $State: Exp $        $Locker:  $
// $Date: 96/06/27 02:55:21 $

#include "nsrLib.h"
#include "nsrRSSdv.h"
#include <stdio.h>
#include <stdlib.h>

INT32
main ( INT16 argc, CHAR_PTR argv[])
{
    Error           tstError;
    String          devfname("tbox");
    extern int      optind;     // For getopt()
    extern CHAR_PTR optarg;     // For getopt()
    INT32           c;
    INT32           showLabels    = 0;
    INT32           showRoot      = 0;
    INT32           showSpace     = 0;
    INT32           showIntegrity = 0;
    INT32           showExecution = 0;
    
    while((c = getopt(argc,argv,"f:lrsixtv")) != EOF) {
        switch(c)
        {
        case 'f':
            devfname      = optarg;
            break;
        case 'l':
            showLabels    = 1;
            break;
        case 'r':
            showRoot      = 1;
            break;
        case 's':
            showSpace     = 1;
            break;
        case 'i':
            showIntegrity = 1;
            break;
        case 'x':
            showExecution = 1;
            break;
        case 't':
            Trace::logAlgorithms(True);
            break;
        case 'v':
            showLabels    = 1;
            showRoot      = 1;
            showSpace     = 1;
            showIntegrity = 1;
            showExecution = 1;
            Trace::logAlgorithms(True);
            break;
        default:
            printf("Usage:  %s [-f devfile] [-lrsxtv]\n",argv[0]);
            printf(" -l : Print Volume Label Information\n");
            printf(" -r : Print Root Directory\n");
            printf(" -s : Print Free Space Information\n");
            printf(" -i : Print Integrity Information\n");
            printf(" -x : Print Execution of this test\n");
            printf(" -t : Print Algorithm flow in UDF Object Framework\n");
            printf(" -v : Print all the above\n");
            break;
        }
    }
    
    if(showExecution) {
        printf("Instantiating Drive Device...");
    }

    DriveDevice ddev(devfname);
    if ( tstError = ddev.error() ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }
    
    if(showExecution) {
        printf("Done.\n");
        printf("Instantiating SSVolume Object...");
    }
    
    SingleSurfaceVolume vol(&ddev);
    // DO NOT check vol.error() here, since it is only valid AFTER
    // fromDisk().

    if(showExecution) {
        printf("Done.\n");
        printf("Invoking SingleSurfaceVolume::fromDisk()...");
    }

    vol.fromDisk(tstError);
    if ( tstError ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }
    
    if(showExecution) {
        printf("Done.\n");
    }

    // Print out the label information if enabled.
    if (showLabels) {
        printf("Volume ID is     '%s'\n",(CONST_CHAR_PTR)vol.physVolumeID());
        printf("Volume Set ID is '%s'\n",(CONST_CHAR_PTR)vol.volumeSetID());
    }

    if(showExecution) {
        printf("Invoking SingleSurfaceVolume::rootICBAddr()...");
    }

    LogExtent rootICBExtent = vol.rootICBAddr(tstError);
    if ( tstError ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf(" ((Root is Block %lu )) ",(UINT32)rootICBExtent.startBlock());
    
        printf("Done.\n");
        printf("Instantiating a Node...");
    }

    Node rootNode(*rootICBExtent.logVolumep());
    if ( tstError = rootNode.error()) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
        printf("Invoking Node::fromDisk()...");
    }

    rootNode.fromDisk(rootICBExtent, tstError);

    if ( tstError ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
        printf("\n");
        rootNode.print(0, "Root Node");
        printf("\n");
        printf("Instantiating a DirList...");
    }

    DirList rootDirList;

    if ( tstError = rootDirList.error() ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
        printf("Instantiating a Buffer %ld bytes long...",
               rootNode.dataEL().infoLen());
    }

    ByteArray rootBuffer( rootNode.dataEL().infoLen() );
    if ( tstError = rootBuffer.error() ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
        printf("Reading Root directory into buffer...");
    }

    rootNode.dataEL().read( rootBuffer, tstError );
    if ( tstError ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
        printf("Invoking DirList::fromISO() on buffer...");
    }

    rootDirList.fromISO( rootBuffer, 0, rootNode.dataEL(), tstError );
    if ( tstError ) {
        if(showExecution) {
            printf("\n Error: %s\n",tstError.message());
        }
        return -1;
    }

    if(showExecution) {
        printf("Done.\n");
    }

    if(showRoot) {
        rootDirList.print( 0, String("Root Directory Contents"));
    }

    ISOSpaceResource & sr = *vol.spaceResourcep();

    if(showSpace) {
        printf("SpaceResource Information:\n");        
        printf("  Available Bytes:    %ld\n",
               sr.availBytes());
        printf("  Maximum Extent Len: %ld\n",
               sr.maxExtLen());
        printf("  Allows Erased:      %s\n",
               sr.allowsErased()?"True":"False");
        printf("  Allows Unerased:    %s\n",
               sr.allowsUnerased()?"True":"False");
    }

    Integrity & integ = *vol.integrityp();
    
    if(showIntegrity) {
        printf("Integrity Information:\n");
        printf("  Unique ID:          %ld\n",
               integ.uniqueID());
        printf("  Number of Files:    %ld\n",
               integ.numFiles());
        printf("  Number of Dirs:     %ld\n",
               integ.numDirectories());
        printf("  Volume Size:        %ld\n",
               integ.size());
        printf("  Free Space:         %ld\n",
               integ.freeSpace());
        printf("  Is Open:            %s\n",
               integ.isOpen()?"True":"False");
        printf("  Is Closed:          %s\n",
               integ.isClosed()?"True":"False");
    }

    return 0;
}
