#include 
#include 
#include 

typedef struct observation_t {
    int time;
    float temperature;
    float pressure;
} observation_t;
typedef struct observation_att_t {
    char* time;
    char* temperature;
    char* pressure;
} observation_att_t;


void
check_err(const int stat, const int line, const char *file) {
    if (stat != NC_NOERR) {
        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
        fflush(stderr);
        exit(1);
    }
}

int
main() {/* create odnc4.nc */

    int  stat;  /* return status */
    int  ncid;  /* netCDF id */

    /* group ids */
    int root_grp;

    /* type ids */
    int observation_t_typ;
    int observation_att_t_typ;

    /* dimension ids */
    int station_dim;
    int observation_dim;

    /* dimension lengths */
    size_t station_len = NC_UNLIMITED;
    size_t observation_len = NC_UNLIMITED;

    /* variable ids */
    int station_id_id;
    int latitude_id;
    int longitude_id;
    int elevation_id;
    int observations_id;

    /* rank (number of dimensions) for each variable */
#   define RANK_station_id 1
#   define RANK_latitude 1
#   define RANK_longitude 1
#   define RANK_elevation 1
#   define RANK_observations 2

    /* variable shapes */
    int station_id_dims[RANK_station_id];
    int latitude_dims[RANK_latitude];
    int longitude_dims[RANK_longitude];
    int elevation_dims[RANK_elevation];
    int observations_dims[RANK_observations];

    /* enter define mode */
    stat = nc_create("odnc4.nc", NC_CLOBBER|NC_NETCDF4, &ncid);
    check_err(stat,__LINE__,__FILE__);
    root_grp = ncid;

    stat = nc_def_compound(root_grp, sizeof(observation_t), "observation_t", &observation_t_typ);    check_err(stat,__LINE__,__FILE__);
    {
    stat = nc_insert_compound(root_grp, observation_t_typ, "time", NC_COMPOUND_OFFSET(observation_t,time), NC_INT);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, observation_t_typ, "temperature", NC_COMPOUND_OFFSET(observation_t,temperature), NC_FLOAT);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, observation_t_typ, "pressure", NC_COMPOUND_OFFSET(observation_t,pressure), NC_FLOAT);    check_err(stat,__LINE__,__FILE__);
    }

    stat = nc_def_compound(root_grp, sizeof(observation_att_t), "observation_att_t", &observation_att_t_typ);    check_err(stat,__LINE__,__FILE__);
    {
    stat = nc_insert_compound(root_grp, observation_att_t_typ, "time", NC_COMPOUND_OFFSET(observation_att_t,time), NC_STRING);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, observation_att_t_typ, "temperature", NC_COMPOUND_OFFSET(observation_att_t,temperature), NC_STRING);    check_err(stat,__LINE__,__FILE__);
    stat = nc_insert_compound(root_grp, observation_att_t_typ, "pressure", NC_COMPOUND_OFFSET(observation_att_t,pressure), NC_STRING);    check_err(stat,__LINE__,__FILE__);
    }


    /* define dimensions */
    stat = nc_def_dim(root_grp, "station", station_len, &station_dim);
    check_err(stat,__LINE__,__FILE__);
    stat = nc_def_dim(root_grp, "observation", observation_len, &observation_dim);
    check_err(stat,__LINE__,__FILE__);

    /* define variables */

    station_id_dims[0] = station_dim;
    stat = nc_def_var(root_grp, "station_id", NC_INT, RANK_station_id, station_id_dims, &station_id_id);
    check_err(stat,__LINE__,__FILE__);

    latitude_dims[0] = station_dim;
    stat = nc_def_var(root_grp, "latitude", NC_FLOAT, RANK_latitude, latitude_dims, &latitude_id);
    check_err(stat,__LINE__,__FILE__);

    longitude_dims[0] = station_dim;
    stat = nc_def_var(root_grp, "longitude", NC_FLOAT, RANK_longitude, longitude_dims, &longitude_id);
    check_err(stat,__LINE__,__FILE__);

    elevation_dims[0] = station_dim;
    stat = nc_def_var(root_grp, "elevation", NC_FLOAT, RANK_elevation, elevation_dims, &elevation_id);
    check_err(stat,__LINE__,__FILE__);

    observations_dims[0] = station_dim;
    observations_dims[1] = observation_dim;
    stat = nc_def_var(root_grp, "observations", observation_t_typ, RANK_observations, observations_dims, &observations_id);
    check_err(stat,__LINE__,__FILE__);

    /* assign global attributes */
    { /* Conventions */
    stat = nc_put_att_text(root_grp, NC_GLOBAL, "Conventions", 6, "CF-2.0");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* CF:featureType */
    stat = nc_put_att_text(root_grp, NC_GLOBAL, "CF:featureType", 17, "stationTimeSeries");
    check_err(stat,__LINE__,__FILE__);
    }


    /* assign per-variable attributes */
    { /* standard_name */
    stat = nc_put_att_text(root_grp, station_id_id, "standard_name", 10, "station_id");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* units */
    stat = nc_put_att_text(root_grp, latitude_id, "units", 13, "degrees_north");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* units */
    stat = nc_put_att_text(root_grp, longitude_id, "units", 12, "degrees_east");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* units */
    stat = nc_put_att_text(root_grp, elevation_id, "units", 4, "feet");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* positive */
    stat = nc_put_att_text(root_grp, elevation_id, "positive", 2, "up");
    check_err(stat,__LINE__,__FILE__);
    }
    { /* coordinates */
    stat = nc_put_att_text(root_grp, observations_id, "coordinates", 46, "observations.time longitude latitude elevation");
    check_err(stat,__LINE__,__FILE__);
    }

    { /* units */
    static const observation_att_t observations_units_att[1] = {{"days since 1929-1-1 0:0:0", "degF", "hectopascal"}} ;
    stat = nc_put_att(root_grp, observations_id, "units", observation_att_t_typ, 1, observations_units_att);    check_err(stat,__LINE__,__FILE__);
    }


    /* leave define mode */
    stat = nc_enddef (root_grp);
    check_err(stat,__LINE__,__FILE__);

    /* assign variable data */

    stat = nc_close(root_grp);
    check_err(stat,__LINE__,__FILE__);
    return 0;
}