from basinmaker.utilities.utilities import Internal_Constant_Names


def add_lakes_and_obs_into_existing_watershed_delineation(
    input_geo_names,
    path_lakefile_in="#",
    lake_attributes=[],
    path_obsfile_in="#",
    obs_attributes=[],
    path_sub_reg_outlets_v="#",
    threshold_con_lake=0,
    threshold_non_con_lake=0,
    only_included_lake_at_river_interction = False,
    search_radius=100,
    sl_connected_lake="#",
    sl_non_connected_lake="#",
    sl_lakes="#",
    path_sub_reg_lake_r="#",
    path_sub_reg_lake_bd_r="#",
    catchment_without_merging_lakes="catchment_without_merging_lakes",
    river_without_merging_lakes="river_without_merging_lakes",
    snapped_obs_points="#",
    cat_use_default_acc="#",
    nfdr_arcgis="#",
    nfdr_grass="#",
    max_memroy=1024 * 4,
    grassdb="#",
    grass_location="#",
    qgis_prefix_path="#",
    gis_platform="qgis",
):
    """Add lake inflow and outflow points as new subabsin outlet

    Update the subbasin delineation result generated by
    "watershed_delineation_without_lake_method". Lake's inflow and outflow
    points will be added into subbasin delineation result as a new subbasin
    outlet. Result from this tool is not the final delineation result.
    Because some lake may cover several subbasins. these subbasin
    are not megered into one subbasin yet.

    Parameters
    ----------
    input_geo_names             : dict
        it is a dictionary that list the required input file names,should at
        least indicate the name of following items:
        fdr_arcgis                   : raster
            it is a raster represent flow direction dataset, which is
            using 1,2,4,...64,128 to represent different directions
        fdr_grass                    : raster
            it is a raster represent flow direction dataset, which is
            using 1 - 8 to represent different directions
        str_r                        : raster
            it is a river network in vector format

        str_v                        : vector
            it is a river network in raster format

        cat_no_lake                  : raster
             it is the raster represent the delineated subbasins without
             considering lakes
        mask                         : raster
            it is a mask raster stored in grass database, which indicate
            the PSE
        dem                          : raster
            it is a dem raster stored in grass database, which is
            has the same extent with MASK.
        acc                          : raster
            it is the raster represent the flow accumulation
    path_lakefile_in            : string (optional)
        It is a string to indicate the full path of the polygon
        shapefile that include lake data.
    lake_attributes             : list
        the columns names that indicate following items has to be included
        1) column name for the unique Id of each lake within the lake polygon shpfile;
        2) column name for type of the lake should be integer;
        3) column name for the volume of the lake in km3;
        4) column name for the average depth of the lake in m;
        5) column name for the area of the lake in km2.
    threshold_con_lake          : float
        It is a lake area thresthold for connected lakes in km2
        Connected Lake with lake area below this value will be
        not added into the subbasin delineation
    threshold_non_con_lake      : float
        It is a lake area thresthold for non-connected lakes in km2
        Non connected Lake with lake area below this value will be
        not added into the subbasin delineation
    path_obsfile_in             : string
        It is a string to indicate the full path of the point
        shapefile that indicate observation gauges
    obs_attributes              : list
        the columns names that indicate following items has to be included
        1) column name for the unique Id of each observation point;
        2) column name for the unique name of each observation point;
        3) column name for the drainage area of each observation point in km3;
        4) column name for the source of the observation point:
            'CA' for observation in canada;
            'US' for observation in US;
    search_radius               : integer
        It is the search ratio in number of grids to snap observation
        point into the river network.
    path_sub_reg_outlets_v      : path
        It is the full path of the subregion outlet vector file
    max_memroy                  : integer
        It is the maximum memeory that allow to be used.
    grassdb                     : path (required)
        It is a path to project grass database folder
    grass_location              : string (required)
        It is a string of grass location name
    qgis_prefix_path            : string (required)
        It is a string of qgis prefix path
    gis_platform                : string
        It is a string indicate with gis platform is used:
        'qgis'                       : the basinmaker is running within QGIS
        'arcgis'                     : the basinmaker is running within ArcGIS
    Notes
    -------
    Raster and vector files that are generated by this function and
    will be used by next step are list as following. All files are
    stored at a grass database

    selected_lakes              : raster
        it is a raster represent all lakes that are selected by two lake
        area threstholds
    sl_nonconnect_lake          : raster
        it is a raster represent all non connected lakes that are selected
        by lake area threstholds
    sl_connected_lake           : raster
        it is a raster represent allconnected lakes that are selected
        by lake area threstholds
    river_without_merging_lakes : raster/vector
        it is the updated river segment for each subbasin
    catchment_without_merging_lakes   : raster/vector
        it is a raster represent updated subbasins after adding lake inflow
        and outflow points as new subbasin outlet.
    snapped_obs_points          : raster/vector
        it is a name of the point gis file represent successfully sanpped
        observation points
    Returns:
    -------
       None

    Examples
    -------

    """

    # define internal file names
    cat_add_lake = Internal_Constant_Names["cat_add_lake"]
    pourpoints_with_lakes = Internal_Constant_Names["pourpoints_with_lakes"]
    pourpoints_add_obs = Internal_Constant_Names["pourpoints_add_obs"]
    lake_outflow_pourpoints = Internal_Constant_Names["lake_outflow_pourpoints"]

    if gis_platform == "qgis":
        assert (
            grassdb != "#"
        ), "grass database folder is needed, when gis_platform = qgis"
        assert (
            grass_location != "#"
        ), "grass location name is needed, when gis_platform = qgis"
        assert (
            qgis_prefix_path != "#"
        ), "qgis prefix path is needed, when gis_platform = qgis"
        from basinmaker.addlakeandobs.addlakesqgis import (
            add_lakes_into_existing_watershed_delineation,
        )
        from basinmaker.addlakeandobs.addobsqgis import add_obs_into_existing_watershed_delineation
        from basinmaker.addlakeandobs.definecatrivqgis import (
            define_cat_and_riv_without_merge_lake_cats,
        )
    elif gis_platform == "arcgis":
        from basinmaker.addlakeandobs.addlakesarcgis import (
            add_lakes_into_existing_watershed_delineation,
        )
    else:
        print('gis_platform    ',gis_platform,'   do not support') 
            
    lake_outflow_pourpoints = add_lakes_into_existing_watershed_delineation(
        grassdb=grassdb,
        grass_location=grass_location,
        qgis_prefix_path=qgis_prefix_path,
        input_geo_names=input_geo_names,
        path_lakefile_in=path_lakefile_in,
        lake_attributes=lake_attributes,
        threshold_con_lake=threshold_con_lake,
        path_sub_reg_lake_r=path_sub_reg_lake_r,
        path_sub_reg_lake_bd_r=path_sub_reg_lake_bd_r,
        threshold_non_con_lake=threshold_non_con_lake,
        only_included_lake_at_river_interction = only_included_lake_at_river_interction,
        sl_connected_lake=sl_connected_lake,
        sl_non_connected_lake=sl_non_connected_lake,
        sl_lakes=sl_lakes,
        nfdr_arcgis=nfdr_arcgis,
        nfdr_grass=nfdr_grass,
        cat_add_lake=cat_add_lake,
        pourpoints_with_lakes=pourpoints_with_lakes,
        cat_use_default_acc=cat_use_default_acc,
        lake_outflow_pourpoints=lake_outflow_pourpoints,
        max_memroy=max_memroy,
    )
    ## add variable into input geo names
    input_geo_names["cat_add_lake"] = cat_add_lake
    input_geo_names["pourpoints_with_lakes"] = pourpoints_with_lakes
    input_geo_names["lake_outflow_pourpoints"] = lake_outflow_pourpoints
    input_geo_names["sl_non_connected_lake"] = sl_non_connected_lake
    input_geo_names["nfdr_grass"] = nfdr_grass

    if path_obsfile_in != "#":
        add_obs_into_existing_watershed_delineation(
            grassdb=grassdb,
            grass_location=grass_location,
            qgis_prefix_path=qgis_prefix_path,
            input_geo_names=input_geo_names,
            path_obsfile_in=path_obsfile_in,
            obs_attributes=obs_attributes,
            search_radius=search_radius,
            path_sub_reg_outlets_v=path_sub_reg_outlets_v,
            max_memroy=max_memroy,
            pourpoints_add_obs=pourpoints_add_obs,
            snapped_obs_points=snapped_obs_points,
        )
    else:
        pourpoints_add_obs = pourpoints_with_lakes

    input_geo_names["pourpoints_add_obs"] = pourpoints_add_obs

    define_cat_and_riv_without_merge_lake_cats(
        grassdb=grassdb,
        grass_location=grass_location,
        qgis_prefix_path=qgis_prefix_path,
        input_geo_names=input_geo_names,
        path_lakefile_in=path_lakefile_in,
        catchment_without_merging_lakes=catchment_without_merging_lakes,
        river_without_merging_lakes=river_without_merging_lakes,
        max_memroy=max_memroy,
    )
