# Copyright (c) 2026 Luigi Paone <ppc.luigi.paone@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause

import gmsh as gm


def logGmshFile(fileName):
    import sys

    if len(sys.argv) < 2:
        print("Usage: " + sys.argv[0] + " file")
        exit

    # gm.initialize()

    # You can run this tutorial on any file that Gmsh can read, e.g. a mesh file in
    # the MSH format: `python t1.py file.msh'

    # gm.open(sys.argv[1])
    gm.open(fileName)

    # Print the model name and dimension:
    print("Model " + gm.model.getCurrent() + " (" + str(gm.model.getDimension()) + "D)")

    # Geometrical data is made of elementary model `entities', called `points'
    # (entities of dimension 0), `curves' (entities of dimension 1), `surfaces'
    # (entities of dimension 2) and `volumes' (entities of dimension 3). As we have
    # seen in the other Python tutorials, elementary model entities are identified
    # by their dimension and by a `tag': a strictly positive identification
    # number. Model entities can be either CAD entities (from the built-in `geo'
    # kernel or from the OpenCASCADE `occ' kernel) or `discrete' entities (defined
    # by a mesh). `Physical groups' are collections of model entities and are also
    # identified by their dimension and by a tag.

    # Get all the elementary entities in the model, as a vector of (dimension, tag)
    # pairs:
    entities = gm.model.getEntities()

    for e in entities:
        # Dimension and tag of the entity:
        dim = e[0]
        tag = e[1]

        # Mesh data is made of `elements' (points, lines, triangles, ...), defined
        # by an ordered list of their `nodes'. Elements and nodes are identified by
        # `tags' as well (strictly positive identification numbers), and are stored
        # ("classified") in the model entity they discretize. Tags for elements and
        # nodes are globally unique (and not only per dimension, like entities).

        # A model entity of dimension 0 (a geometrical point) will contain a mesh
        # element of type point, as well as a mesh node. A model curve will contain
        # line elements as well as its interior nodes, while its boundary nodes will
        # be stored in the bounding model points. A model surface will contain
        # triangular and/or quadrangular elements and all the nodes not classified
        # on its boundary or on its embedded entities. A model volume will contain
        # tetrahedra, hexahedra, etc. and all the nodes not classified on its
        # boundary or on its embedded entities.

        # Get the mesh nodes for the entity (dim, tag):
        nodeTags, nodeCoords, nodeParams = gm.model.mesh.getNodes(dim, tag)

        # Get the mesh elements for the entity (dim, tag):
        elemTypes, elemTags, elemNodeTags = gm.model.mesh.getElements(dim, tag)

        # Elements can also be obtained by type, by using `getElementTypes()'
        # followed by `getElementsByType()'.

        # Let's print a summary of the information available on the entity and its
        # mesh.

        # * Type and name of the entity:
        type = gm.model.getType(e[0], e[1])
        name = gm.model.getEntityName(e[0], e[1])
        if len(name):
            name += " "
        print("Entity " + name + str(e) + " of type " + type)

        # * Number of mesh nodes and elements:
        numElem = sum(len(i) for i in elemTags)
        print(
            " - Mesh has "
            + str(len(nodeTags))
            + " nodes and "
            + str(numElem)
            + " elements"
        )

        # * Upward and downward adjacencies:
        up, down = gm.model.getAdjacencies(e[0], e[1])
        if len(up):
            print(" - Upward adjacencies: " + str(up))
        if len(down):
            print(" - Downward adjacencies: " + str(down))

        # * Does the entity belong to physical groups?
        physicalTags = gm.model.getPhysicalGroupsForEntity(dim, tag)
        if len(physicalTags):
            s = ""
            for p in physicalTags:
                n = gm.model.getPhysicalName(dim, p)
                if n:
                    n += " "
                s += n + "(" + str(dim) + ", " + str(p) + ") "
            print(" - Physical groups: " + s)

        # * Is the entity a partition entity? If so, what is its parent entity?
        partitions = gm.model.getPartitions(e[0], e[1])
        if len(partitions):
            print(
                " - Partition tags: "
                + str(partitions)
                + " - parent entity "
                + str(gm.model.getParent(e[0], e[1]))
            )

        # * List all types of elements making up the mesh of the entity:
        for t in elemTypes:
            name, dim, order, numv, parv, _ = gm.model.mesh.getElementProperties(t)
            print(
                " - Element type: "
                + name
                + ", order "
                + str(order)
                + " ("
                + str(numv)
                + " nodes in param coord: "
                + str(parv)
                + ")"
            )

    # We can use this to clear all the model data but after i need to reinitialize gm:
    #
    # gm.clear()
    # gm.finalize()
