 # -*- coding: utf-8 -*-
"""
Created on Wed Aug 23 07:56:23 2023

@author: lcassan
"""
import sys
import os
'''
#from centerline.geometry import Centerline
import geopandas as gpd
from scipy.interpolate import splprep, splev
from shapely.geometry import Point
workflow_dir ='/space/globc/cassan/CARS/RT_Hydro/demo_workflow/Scripts/'
raster_dir = '/space/globc/cassan/CARS/RT_Hydro/demo_workflow/'

parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),'..'))
sys.path.append(parent_dir)
sys.path.append(workflow_dir)
sys.path.append(raster_dir)
'''


from os import getcwd, path
import argparse
from core.ModelCatchment import ModelCatchment
from core.Hydraulics import *
from core.CrossSection import *
from core.Bathymetrics import *
from shapely.geometry import Point
from shapely.geometry import LineString


# CLI argument parser
parser = argparse.ArgumentParser(description='a CLI (command line interface) for CEPHEE')
parser.add_argument('parameter_file', help='Provide parameter file')
args = parser.parse_args()

# read input files
if not path.isfile(args.parameter_file):
    raise SystemExit(args.parameter_file + ' file not found')

# Créer un dictionnaire pour stocker les variables et classes définies dans le fichier
name= {}
# Ouvrir et lire le fichier Python
with open(args.parameter_file, "r") as file:
    code = file.read()
# Exécuter le contenu du fichier dans le namespace
exec(code,name)
Param = name.get('Parameters')
params =Param()

#Force certains paramètres à avoir un sens physique pour ce workflow (un seul tronçon, pas de MNT)
params['C']['findCatchment'] = False
params['C']['computeGlobal'] = False
params['C']['DEM_file_extension'] = '.tif'
params['H']['createBanksMethods'] = 'Obs'
params['H']['dischargeMethod'] = 'Constant'
params['B']['interpolationMethod'] = params['H']['createBanksMethods']
if params['XS']['creation_step'] <= params['XS']['interpolation_step']:
    params['XS']['interpolate_XS'] = False
filename_mask = params['B']['riverbanks_filepath']

#-----------------------------------------------------------------------------
#instanciation du modèle
BV1=ModelCatchment()
params.user_outlet_point = Point(471339,6382306)

#-------EXECUTION DATA ----------------------------------------------------
#-----------------------------------------------------------------------------
#lecture des données topo
BV1.read_network(river_filename=params['N']['network_filepath'], nclassemax=params['N']['classeMax'])
BV1.outlet_point = params.user_outlet_point
BV1.read_DEM_stack(DEM_path_ext=(params['C']['DEM_path'], params['C']['DEM_file_extension']))
BV1.clipRiverFromDEM()
print('DEM and Network read')

#attribue un z à la centerline, remplace la fonction de projection qui n'est pas possible sans MNT dans le lit
for i, row in BV1.hydro_network.iterrows():
    line = row['geometry']
    if BV1.network_type == 'SWORD':
        wse =  row['Classe']
        line_with_z = LineString(
            [(x, y, wse + 0.001*i) for i, (x, y) in enumerate(zip(line.xy[0], line.xy[1]))])
    else:
        line_with_z =  LineString(
                    [(x, y, 0) for x, y in zip(line.xy[0], line.xy[1])])

    BV1.hydro_network.loc[i,'geometry'] = line_with_z

print('Network projection completed')


#-----------------------------------------------------------------------------
#Traitement du reséau pour le mettre au standard hydraulique 'utilisable par un code 1D)

if  BV1.network_type == 'SWORD': # on peut ordonner le réseau grâce au wse
    BV1.hydro_network['River'] = BV1.hydro_network['gid']
    BV1.order_network(params['N']['minDistJunction'])
    #BV1.list_of_outlet = [[BV1.ordered_network['River'].iloc[0] , [BV1.ordered_network['River'].iloc[0]], 0]]

else:
    BV1.ordered_network = BV1.hydro_network
    BV1.ordered_network['River'] = BV1.ordered_network['gid']

BV1.find_junctionAndOutlet(params['N']['minDistJunction']) #trouve la position des confluences et les exutoires
BV1.setOutlet(params.user_outlet_point)                                                     # param=distance minimale entre 2 reachs pour connexion
BV1.renameReachFromJunction(params) # crée les biefs et renomme les biefs en fonction de la position des tronçons
BV1.createReach()

network_filepath = os.path.join(params.work_path, 'ordered_network.shp')
BV1.ordered_network.to_file(network_filepath)
BV1.junction.to_file(os.path.join(params.work_path, 'junction.shp'))

if params['B']['useImportedSections']:
    importXSlines(BV1, params, XS_filepath=params['XS']['XS_filepath'])
else:
    BV1.interpolateReach(params['XS']['creation_step']) #interpole les tronçons de la distance fournit en argument
    createXSlines(BV1, params['XS']['width'], params['XS']['number_of_points'])
    if params['XS']['optimizeXS']:
        optimize_XS_lines(BV1)
    project_XS_lines(BV1, params)

if params['XS']['interpolate_XS']:
    interpolate_XS_lines(BV1, params)

XS_lines_filepath = os.path.join(params.work_path, 'XS_lines.shp')
saveXSlines(BV1, XS_lines_filepath)
print('Cross section created')

addQtoSection(BV1,params)
setConstantFriction(BV1,params['H']['frictionValue'])
polygone_file = polygonize_water_mask(filename_mask,params,5)

drag_all_XS(BV1, params, type_comp=params['B']['interpolationMethod'],riverbanks_filepath =polygone_file )  # create the line of each section with the points of the banks
if params['H']['mapping_method'] == 'interpolation':
    interpolate_DEM_channel(BV1, params)
else:
    rasterize_DEM_channel(BV1, params)


MergeRaster_channel_DEM(BV1,  params.work_path)

