#!/usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
# $Id$
#
# Project:  GDAL/OGR Test Suite
# Purpose:  Generate test_s102.h5
# Author:   Even Rouault <even dot rouault at spatialys.com>
#
###############################################################################
# Copyright (c) 2023, Even Rouault <even dot rouault at spatialys.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################

import os

import h5py
import numpy as np


def generate(filename, version, with_QualityOfSurvey=False):
    f = h5py.File(os.path.join(os.path.dirname(__file__), f"{filename}.h5"), "w")
    BathymetryCoverage = f.create_group("BathymetryCoverage")
    BathymetryCoverage_01 = BathymetryCoverage.create_group("BathymetryCoverage.01")
    Group_001 = BathymetryCoverage_01.create_group("Group_001")

    values_struct_type = np.dtype(
        [
            ("depth", "f4"),
            ("uncertainty", "f4"),
        ]
    )
    values = Group_001.create_dataset("values", (2, 3), dtype=values_struct_type)
    data = np.array(
        [(0, 100), (1, 101), (2, 102), (1e6, 103), (4, 1e6), (5, 105)],
        dtype=values_struct_type,
    ).reshape(values.shape)
    values[...] = data

    Group_001.attrs["minimumUncertainty"] = np.float32(100)
    Group_001.attrs["maximumUncertainty"] = np.float32(105)
    Group_001.attrs["minimumDepth"] = np.float32(0)
    Group_001.attrs["maximumDepth"] = np.float32(5)

    BathymetryCoverage_01.attrs["gridOriginLongitude"] = np.float64(2)
    BathymetryCoverage_01.attrs["gridOriginLatitude"] = np.float64(48)
    BathymetryCoverage_01.attrs["gridSpacingLongitudinal"] = np.float64(0.4)
    BathymetryCoverage_01.attrs["gridSpacingLatitudinal"] = np.float64(0.5)
    BathymetryCoverage_01.attrs["numPointsLongitudinal"] = np.uint32(values.shape[1])
    BathymetryCoverage_01.attrs["numPointsLatitudinal"] = np.uint32(values.shape[0])

    group_f = f.create_group("Group_F")

    f.attrs["issueDate"] = "2023-12-31"
    f.attrs["geographicIdentifier"] = "Somewhere"
    f.attrs["verticalDatum"] = np.int16(12)
    if version == "INT.IHO.S-102.2.2":
        f.attrs["horizontalCRS"] = np.int32(4326)
        f.attrs["verticalCS"] = np.int32(6498)  # Depth, metres, orientation down
        f.attrs["verticalCoordinateBase"] = np.int32(2)
        f.attrs["verticalDatumReference"] = np.int32(1)
    else:
        assert version == "INT.IHO.S-102.2.1"
        f.attrs["horizontalDatumReference"] = "EPSG"
        f.attrs["horizontalDatumValue"] = np.int32(4326)
    f.attrs["productSpecification"] = version
    f.attrs[
        "producer"
    ] = "Generated by autotest/gdrivers/data/s102/generate_test.py (not strictly fully S102 compliant)"
    f.attrs["metadata"] = f"MD_{filename}.xml"

    open(os.path.join(os.path.dirname(__file__), f.attrs["metadata"]), "wb").write(
        b"<nothing/>"
    )

    if with_QualityOfSurvey:
        QualityOfSurvey = f.create_group("QualityOfSurvey")
        QualityOfSurvey_01 = QualityOfSurvey.create_group("QualityOfSurvey.01")

        for attr_name in (
            "gridOriginLongitude",
            "gridOriginLatitude",
            "gridSpacingLongitudinal",
            "gridSpacingLatitudinal",
            "numPointsLongitudinal",
            "numPointsLatitudinal",
        ):
            QualityOfSurvey_01.attrs[attr_name] = BathymetryCoverage_01.attrs[attr_name]

        Group_001 = QualityOfSurvey_01.create_group("Group_001")

        values = Group_001.create_dataset("values", (2, 3), dtype=np.uint32)
        data = np.array(
            [0, 1, 2, 1000000, 3, 2],
            dtype=np.uint32,
        ).reshape(values.shape)
        values[...] = data

        featureAttributeTable_struct_type = np.dtype(
            [
                ("id", "u4"),
                ("floatval", "f4"),
                ("strval", "S2"),
            ]
        )

        featureAttributeTable = QualityOfSurvey.create_dataset(
            "featureAttributeTable", (5,), dtype=featureAttributeTable_struct_type
        )

        data = np.array(
            [
                (0, 1.5, "a"),
                (1, 2.5, "b"),
                (2, 3.5, "c"),
                (3, 4.5, "d"),
                (1000000, 5.5, "e"),
            ],
            dtype=featureAttributeTable_struct_type,
        )
        featureAttributeTable[...] = data

        GroupFQualityOfSurvey_struct_type = np.dtype(
            [
                ("code", "S16"),
                ("name", "S16"),
                ("uom.name", "S16"),
                ("fillValue", "S16"),
                ("datatype", "S16"),
                ("lower", "S16"),
                ("upper", "S16"),
                ("closure", "S16"),
            ]
        )
        GroupFQualityOfSurvey = group_f.create_dataset(
            "QualityOfSurvey", (1,), dtype=GroupFQualityOfSurvey_struct_type
        )
        GroupFQualityOfSurvey[...] = np.array(
            [("id", "", "", "0", "H5T_INTEGER", "1", "", "geSemiInterval")],
            dtype=GroupFQualityOfSurvey_struct_type,
        )


generate("test_s102_v2.1", "INT.IHO.S-102.2.1")
generate("test_s102_v2.2", "INT.IHO.S-102.2.2")

generate(
    "test_s102_v2.2_with_QualityOfSurvey",
    "INT.IHO.S-102.2.2",
    with_QualityOfSurvey=True,
)
