/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by  The HDF Group and                                           *
 * The Board of Trustees of the University of Illinois.                      *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of H4H5TOOLS. The full H4H5TOOLS copyright notice,      *
 * including terms governing use, modification, and redistribution, is       *
 * contained in the COPYING file, which can be found at the root of the      *
 * source code distribution tree. The copyright notice can also be found     *
 * at https://www.hdfgroup.org/licenses.  If you do not have access to       *
 * either file, you may request a copy from help@hdfgroup.org.               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "h4toh5.h"

/*
     This file is h4h5apitestdefault.c.

     1) will test the default settings for h4toh5 library APIs.
     2) will test the hardlink feature of h4toh5 library.
*/

/*-------------------------------------------------------------------------
 * Function:    main
 *
 * Return:  FAIL if failed, SUCCEED if successful.
 *-------------------------------------------------------------------------
 */


int main() {

    hid_t                   h4toh5id; /*h4toh5 id*/
    int32                   file_id; /* HDF4 file id*/
    int32                   sd_id;   /* HDF4 SD id*/
    int32                   gr_id;   /* HDF4 GR id*/
    int32                   sds_id;  /* HDF4 SDS id*/
    int32                   image_id; /*HDF4 image id*/
    int32                   vgroup_id; /*HDF4 vgroup id*/
    int32                   vdata_id; /*HDF4 vdata id*/
    int32                   vdata_ref; /*HDF4 vdata reference number*/
    int32                   vgroup_ref;/*HDF4 vgroup reference number*/
    int32                   anno_objref;/*HDF4 annotation object reference number*/
    int32                   anno_objtag;/*HDF4 annotation object tag */
    int32                   status; /*temporary variable to check status of HDF4 APIs */
    int                     h4toh5status; /*temporary variable to check status of H4toH5 APIs */
/* for object name output testing
    char*                   h5sdsname;
    char*                   h5imagename;
    char*                   h5vdataname;
    char*                   h5vgroupname;
*/


    /** open H(DF4) interface **/
    file_id = Hopen("vg_all_test.hdf",DFACC_READ,0);
    if(file_id == FAIL) {
        printf("cannot open H interface.\n");
        return FAIL;
    }

    /** open SD interface **/
    sd_id = SDstart("vg_all_test.hdf",DFACC_READ);
    if(sd_id == FAIL) {
        printf("cannot start SD interface.\n");
        Hclose(file_id);
        return FAIL;
    }

    /** open GR  interface**/
    gr_id = GRstart(file_id);
    if(gr_id == FAIL) {
        printf("cannot obtain gr id.\n");
        SDend(sd_id);
        Hclose(file_id);
        return FAIL;
    }

    /** open V interface **/
    status = Vstart(file_id);
    if(status == FAIL) {
        printf("cannot start V interface.\n");
        SDend(sd_id);
        GRend(gr_id);
        Hclose(file_id);
        return FAIL;
    }

    if((h4toh5id = H4toH5open("vg_all_test.hdf","vg_all_test.h5",H425_CLOBBER)) < 0) {
        printf("cannot open H4toH5 interface\n");
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        return FAIL;
    }

    /* category I. test all APIs with the default name. */

    /* 1. testing SDS API; choose the SDS object with index 0;
                all attributes and dimensional scales of this SDS will
                be converted. */
    sds_id = SDselect(sd_id,0);
    if(sds_id == FAIL) {
        printf("cannot obtain SDS id.\n");
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* do H4 to H5 SDS conversion with all default settings. */
    if(H4toH5sds(h4toh5id,sds_id,"/group1",NULL,NULL,1,1)<0) {
        printf("cannot convert SDS\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

#if 0
    /* for testing generation of the absolute path of SDS object */
    h5sdsname = H4toH5get_SDS_name(h4toh5id,sds_id,"/group1");
    printf("h5sdsname %s\n",h5sdsname);
    free(h5sdsname);
#endif


    /* 2. testing gr API. */

    /* obtain a gr id. */
    image_id = GRselect(gr_id,0);
    if(image_id == FAIL) {
        printf(" cannot obtain image id.\n");
        SDendaccess(sds_id);
         SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* convert image. */
    if(H4toH5image(h4toh5id,image_id,"/group1",NULL,NULL,NULL,1,1)<0){
        printf("cannot convert image\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }


#if 0
    /* for testing absolute name of image object. */
    h5imagename = H4toH5get_image_name(h4toh5id,image_id,"/group1");
    printf("h5imagename %s\n",h5imagename);
    free(h5imagename);
#endif

    /* 3. testing independent vdata conversion API.
         Since Vdata may be attributes, in order to avoid converting attributes;
         we use hdp to find the reference number of an independent vdata in this
         file and obtain vdata id later. */

    vdata_ref = 9;
    vdata_id = VSattach(file_id,vdata_ref,"r");

    if(vdata_id == FAIL) {
        printf("cannot obtain Vdata id. \n");
        SDendaccess(sds_id);
        GRendaccess(image_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*convert vdata */
    if(H4toH5vdata(h4toh5id,vdata_id,"/group1",NULL,1)<0) {
        printf("error H4toH5vdata\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }
#if 0
    /* for testing the absolute path of vdata */
    h5vdataname = H4toH5get_vdata_name(h4toh5id,vdata_id,"/group1");
    printf("h5vdataname %s\n",h5vdataname);
    free(h5vdataname);
#endif
    /* 4. testing partial vgroup API.
         vgroup itself and vgroup with non-vgroup members will be converted. */

    /* obtaining a vgroup reference number. */
    vgroup_ref = Vgetid(file_id,-1);
    if(vgroup_ref == FAIL){
        printf("cannot obtain vgroup reference number.\n");
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* obtaining a vgroup id. */
    vgroup_id = Vattach(file_id,vgroup_ref,"r");
    if(vgroup_id == FAIL){
        printf("cannot obtain Vgroup id.\n");
         SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* converting vgroup with an image object. */
    if(H4toH5bas_vgroup(h4toh5id,vgroup_id,"/gpartial",NULL,1,1)<0){
        printf("basic vgroup conversion test failed\n");
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        H4toH5error_get(h4toh5id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*5. testing the whole vgroup API.
        Everything under this vgroup is converted.*/
    if(H4toH5adv_group(h4toh5id,vgroup_id,"/gwhole",NULL,H425_OSPEC_ALLATTRS)<0){
        printf("advanced vgroup conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*6. testing annotation API. */

    /* convert all file labels. */
    if(H4toH5anno_file_all_labels(h4toh5id)<0) {
        printf("file label conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* convert all file descriptions. */
    if(H4toH5anno_file_all_descs(h4toh5id)<0) {
        printf("file description conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /***** object annotations testing, we have to provide the object reference
                 number and object tag that have annotations associate with it.
                 we will use hdp to check the reference of such object. In this
                 example, vgroup is used. vgroup tag is 1965. vgroup reference is 4.
                 *****/

    anno_objref = 4;
    anno_objtag = 1965;

    if(H4toH5anno_obj_label(h4toh5id,"/","/group1",anno_objref,
             anno_objtag,NULL,0)<0){
        printf("object label conversion test fails.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5anno_obj_desc(h4toh5id,"/","/group1",anno_objref,
             anno_objtag,NULL,0)<0){
        printf("object description conversion test fails.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*7. testing palette conversion.
             Note: We only tested default parameters;
                         since we already used a default palette group
                         "/HDF4_PALGROUP" when converting the image; so
                         we made another palette group for this test.*/
    if(H4toH5pal(h4toh5id,image_id,NULL,NULL,"/paltestgroup",NULL,1,0)<0){
        printf("H4toH5 palette conversion failed.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* 8. testing dimensional scale dataset API. */
    if(H4toH5all_dimscale(h4toh5id,sds_id,"/group1","sds","/dimtestgroup",1,0) <0) {
        printf("H4toH5 dimensional scale testing is wrong.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*9. testing global attributes of SD and GR interfaces. */
    if(H4toH5glo_sds_attr(h4toh5id,H425_OSPEC_ALLATTRS)<0) {
        printf("SD interface attribute conversion failed\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5glo_image_attr(h4toh5id, H425_OSPEC_ALLATTRS)<0) {
        printf("GR interface attribute conversion failed\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }


     /* category II. test all API with user-defined name. */

    /* II.1. testing SDS API; choose the SDS object with index 0;
                all attributes and dimensional scales of this SDS will
                be converted. */
    if(H4toH5sds(h4toh5id,sds_id,"/group1u","mysds","/mydimgroup",1,1)<0) {
        printf("SDS conversion test failed for non-default object name\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* II.2. testing gr API. */
    /* obtain a gr id. */

    if(H4toH5image(h4toh5id,image_id,"/group1u","myimage","/mypalgroup","mypal",1,1)<0){
        printf("image conversion test failed for non-default object name\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* II.3. testing independent vdata conversion API.
     */

    if(H4toH5vdata(h4toh5id,vdata_id,"/group1u","myvdata",1)<0) {
        printf("vdata conversion test failed for user-defined names\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* II.4. testing partial vgroup API.
         vgroup itself and vgroup with non-vgroup members will be converted. */

    /* converting vgroup with an image object. */
    if(H4toH5bas_vgroup(h4toh5id,vgroup_id,"/gpartial","myvgroup",1,1)<0){
        printf("basic vgroup test failed for user-defined names\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*II.5. testing the whole vgroup API.
        Everything under this vgroup is converted.*/
    if(H4toH5adv_group(h4toh5id,vgroup_id,"/gwhole","myallvgroup",H425_OSPEC_ALLATTRS)<0){
        printf("advanced vgroup test failed for user-defined names\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /***** object annotations testing, user provides the attribute names.
                 *****/

    if(H4toH5anno_obj_label(h4toh5id,"/","/group1",anno_objref,
             anno_objtag,"myobjlabel",0)<0){
        printf("annotation object label test failed for user-defined names.\n");
         H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
         SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    if(H4toH5anno_obj_desc(h4toh5id,"/","/group1",anno_objref,
             anno_objtag,"myobjdesc",0)<0){
        printf("annotation object description tested failed");
        printf(" for user-defined names. \n");
         H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
         SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
        return FAIL;
    }

    /*II.7. testing palette conversion.
             Note: We only tested default parameters;
                         since we already used a default palette group
                         "/HDF4_PALGROUP" when converting the image; so
                         we made another palette group for this test.*/

    if(H4toH5pal(h4toh5id,image_id,"/group1","image","/paltestgroup","myownpal",1,0)<0){
        printf("palette conversion test failed for user-defined names.\n");
        H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
        SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
        return FAIL;
    }

    /* II.8. testing one dimensional scale dataset API. */
    if(H4toH5one_dimscale(h4toh5id,sds_id,"/group1","sds","/mydimtestgroup","myowndim_ofindex0",1,1,0) <0) {
        printf("H4toH5 dimensional scale testing is wrong.\n");
        H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
        SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
        return FAIL;
    }

    /* II.9. testing file annotation label and description with user-defined name. */
    if(H4toH5anno_file_label(h4toh5id,"myfilelabel",0) <0){
            printf("file label conversion test failed with user-defined name\n");
            H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
            return FAIL;
    }

    if(H4toH5anno_file_desc(h4toh5id,"myfiledesc",0) <0){
            printf("file description conversion test failed with user-defined name\n");
            H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
         GRendaccess(image_id);
         VSdetach(vdata_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
            return FAIL;
    }

    status = VSdetach(vdata_id);
    if(status == FAIL) {
        printf("cannot detach VS interface.\n");
        SDendaccess(sds_id);
         GRendaccess(image_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
            return FAIL;
    }
    status = Vdetach(vgroup_id);
    if(status == FAIL) {
        printf("cannot detach V interface. \n");
        SDendaccess(sds_id);
         GRendaccess(image_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
    }

    status = SDendaccess(sds_id);
    if(status == FAIL) {
        printf("cannot end SDS interface. \n");
         GRendaccess(image_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
    }

    status = GRendaccess(image_id);
    if(status == FAIL) {
        printf("cannot end image interface. \n");
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
    }
    status = Vend(file_id);
    if(status == FAIL) {
        printf("cannot end V interface. \n");
         SDend(sd_id);
         GRend(gr_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
    }

    status = GRend(gr_id);
    if(status == FAIL) {
        printf("cannot end GR interface. \n");
            SDend(sd_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }
    status = SDend(sd_id);
    if(status == FAIL) {
        printf("cannot end SD interface. \n");
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }
    status = Hclose(file_id);
    if(status == FAIL) {
        printf("cannot end H interface. \n");
         H4toH5close(h4toh5id);
         return FAIL;
    }
    h4toh5status = H4toH5close(h4toh5id);
    if(h4toh5status == FAIL) {
        printf("cannot close H4toH5 interface. \n");
        return FAIL;
    }
        return SUCCEED;
}

