import os, setuptools, sys, sysconfig;
from pkg_resources import packaging

# https://stackoverflow.com/questions/14320220/testing-python-c-libraries-get-build-path
def distutils_dir_name( dir_name ):
    """Returns the name of a distutils build directory"""
    f = "{dirname}.{platform}-{cache_tag}"
    my_cache_tag = sys.implementation.cache_tag
    if packaging.version.parse( setuptools.__version__) < packaging.version.parse( "62.1.0"):
        my_cache_tag = str( sys.version_info.major) + '.' + str( sys.version_info.minor)
    return f.format(dirname = dir_name,
                    platform = sysconfig.get_platform(),
                    cache_tag = my_cache_tag)

# get build path of module
python_so_extension = sysconfig.get_config_var('EXT_SUFFIX')

module_path = os.path.join('build', distutils_dir_name( 'lib'))
sys.path.insert( 1, module_path)

import gidpost

def error_exit( filename, code, msg):
    print( "* ERROR writing file " + filename)
    print( "* ", msg)
    print( "* code =", code)
    exit( 1)

def copy_to_intArray( int_array, list):
    idx = 0
    for value in list:
        gidpost.intArray_setitem( int_array, idx, value)
        idx = idx + 1

def copy_to_doubleArray( double_array, list):
    idx = 0
    for value in list:
        gidpost.doubleArray_setitem( double_array, idx, value)
        idx = idx + 1

format = gidpost.GiD_PostHDF5
# format = gidpost.GiD_PostAscii

test_filename = "gidpost-test-array.post.h5"
if ( format == gidpost.GiD_PostAscii):
    test_filename = "gidpost-test-array.post.msh"

fail = 0

print( "version =", gidpost.GiD_PostGetVersion())
print( "is thread safe =", "yes" if gidpost.GiD_PostIsThreadSafe( gidpost.GiD_PostHDF5) else "no")

fail = gidpost.GiD_PostInit()
if ( fail): error_exit( test_filename, fail, "in GiD_PostInit()")

# ascii post output writes 2 files : *.post.msh and *.post.res
# hdf5 post output writes 1 file
file_id = 0;
if ( format == gidpost.GiD_PostAscii):
    file_id = gidpost.GiD_fOpenPostMeshFile( test_filename, format)
    if ( file_id == 0): fail = 1
    if ( fail): error_exit( test_filename, fail, "in GiD_fOpenPostMeshFile()")
else:
    file_id = gidpost.GiD_fOpenPostResultFile( test_filename, format)
    if ( file_id == 0): fail = 1
    if ( fail): error_exit( test_filename, fail, "in GiD_fOpenPostResultFile()")

# 2 meshes : 1 with triangles and 1 with quadrilaterals
# the 1st mesh will contain all the coordinates for both meshes

gidpost.GiD_fBeginMeshColor( file_id, "test gp_py triangles", gidpost.GiD_3D, gidpost.GiD_Triangle, 3, 0.6, 0.5, 0.4)

# Create and Write coordinates:
num_nodes = 6
# we could have skipped the id's as they are all consecutive
coords_list_ids = gidpost.new_intArray( num_nodes)
copy_to_intArray( coords_list_ids, range( 1, 7))  # list = 1, 2, 3, 4, 5, 6
coords_list_xyz = gidpost.new_doubleArray( num_nodes * 3)
copy_to_doubleArray( coords_list_xyz, [ 
    0.0, 0.0, 0.0,
    1.0, 0.0, 0.0,
    1.0, 1.0, 0.0,
    0.0, 1.0, 0.0,
    2.0, 0.0, 0.0, 
    2.0, 1.0, 0.0
    ])

fail = gidpost.GiD_fWriteCoordinatesIdBlock( file_id, num_nodes, coords_list_ids, coords_list_xyz)
if ( fail): error_exit( test_filename, fail, "in GiD_fBeginMeshColor()/GiD_fWriteCoordinatesIdBlock()")

# Create and Write connectivity array for each element
# two triangles
num_triangles = 2
triangs_list_ids = gidpost.new_intArray( num_triangles)
copy_to_intArray( triangs_list_ids, [ 1, 2])
triangs_connectivities = gidpost.new_intArray( num_triangles * 3)
copy_to_intArray( triangs_connectivities, [ 
    1 , 2, 3,
    1 , 3, 4
    ])

fail = gidpost.GiD_fWriteElementsIdBlock( file_id, num_triangles, triangs_list_ids, triangs_connectivities)
if ( fail): error_exit( test_filename, fail, "in GiD_fWriteElementsIdBlock() triangles")

gidpost.GiD_fBeginMeshColor( file_id, "test gp_py quadrilaterals", gidpost.GiD_3D, gidpost.GiD_Quadrilateral, 4, 0.8, 0.2, 0.5)
# if we had more coordinates, like nodes 5 and 6 above, we could have written them here...
# 1 quadrilateral
num_quads = 1
quads_list_ids = gidpost.new_intArray( num_quads)
copy_to_intArray( quads_list_ids, [ 3])
quads_connectivities = gidpost.new_intArray( num_quads * 4)
copy_to_intArray( quads_connectivities, [ 2 , 5, 6, 3])
fail = gidpost.GiD_fWriteElementsIdBlock( file_id, num_quads, quads_list_ids, quads_connectivities)
if ( fail): error_exit( test_filename, fail, "in GiD_fWriteElementsIdBlock() triangles")


# ascii post output writes 2 files : *.post.msh and *.post.res
# hdf5 post output writes 1 file
if ( format == gidpost.GiD_PostAscii):
    fail = gidpost.GiD_fClosePostMeshFile( file_id)
    if ( fail): error_exit( test_filename, fail, "in GiD_fClosePostMeshFile()")
    test_filename = "gidpost-test-array.post.res"
    file_id = gidpost.GiD_fOpenPostResultFile( test_filename, format)
    if ( file_id == 0): fail = 1
    if ( fail): error_exit( test_filename, fail, "in GiD_fOpenPostResultFile()")

# Writing results

# define gauss point 'elemental' or use standard GP_ELEMENT_1
# gidpost.GiD_fBeginGaussPoint( file_id, "elemental", gidpost.GiD_Triangle, "__all__", 1, 0, 1)
# fail = gidpost.GiD_fEndGaussPoint( file_id);
# if ( fail): error_exit( test_filename, fail, "in ")

# id's are the same as nodes
scalar_nodes = gidpost.new_doubleArray( num_nodes * 1)
copy_to_doubleArray( scalar_nodes, [ 10.1, 20.2, 30.3, 40.4, 50.5, 60.6])
list_comp_names = gidpost.new_stringArray( 0);
fail = gidpost.GiD_fWriteResultBlock( file_id, "test nodal", "gidpost", 1.0, 
                                     gidpost.GiD_Scalar, gidpost.GiD_OnNodes, "", "", 0, list_comp_names, 
                                     num_nodes, coords_list_ids, 1, scalar_nodes)
if ( fail): error_exit( test_filename, fail, "in writing result test nodal")

num_elements = num_triangles + num_quads
elements_list_ids = gidpost.new_intArray( num_elements)
copy_to_intArray( elements_list_ids, range( 1, num_elements + 1)),
scalar_elemental = gidpost.new_doubleArray( num_elements * 1)
copy_to_doubleArray( scalar_elemental, [ 11.1, 22.2, 33.3])
fail = gidpost.GiD_fWriteResultBlock( file_id, "test elemental", "gidpost", 1.0, 
                                     gidpost.GiD_Scalar, gidpost.GiD_OnGaussPoints, "GP_ELEMENT_1", "", 0, list_comp_names, 
                                     num_elements, elements_list_ids, 1, scalar_elemental)
if ( fail): error_exit( test_filename, fail, "in writing result test elemental")

fail = gidpost.GiD_fClosePostResultFile( file_id)
if ( fail): error_exit( test_filename, fail, "in GiD_fClosePostResultFile()")
fail = gidpost.GiD_PostDone()
if ( fail): error_exit( test_filename, fail, "in GiD_PostDone()")

gidpost.delete_intArray( coords_list_ids)
gidpost.delete_intArray( triangs_list_ids)
gidpost.delete_intArray( triangs_connectivities)
gidpost.delete_intArray( quads_list_ids)
gidpost.delete_intArray( quads_connectivities)
gidpost.delete_intArray( elements_list_ids)

gidpost.delete_doubleArray( coords_list_xyz)
gidpost.delete_doubleArray( scalar_nodes)
gidpost.delete_doubleArray( scalar_elemental)

print( '* gidpost file created: ' + test_filename)
