""" 
 Tool Name:  CreatePolygons
 Description: Creates updated polygon feature classes from updated lines feature class
 Author: Patrick Longley (plongley@usgs.gov)
 Created: 09/17/2020
 Language: Written in python3 (arcpro).
 History: 
    10/06/2020 validation, 
    10/06/2020 constants, 
    10/06/2020, metadata
    10/15/2020 general review
"""

import os
import sys
import re
import arcpy
import wbd_params
import wbd_f
import wbd_c
import geometry_createtopology

# Constants
PYTHON_VERSION = sys.version_info.major
MEMORY_FPATH = wbd_f.get_memoryfpath(PYTHON_VERSION)

template_dict = wbd_f.template_dict
class CreatePolygons(object):
    """
    Creates updated polygon feature classes from updated lines feature class

    Args:
        linefc_updated (str): updated WBD line feature class
        wbdpolygon_labelpnt (list of strings): WBD polygon label point feature classes
    Outputs:
        returns: None

    """
    def __init__(self):
        """
        Initialize variables
        """
        self.label       = "3) Create Polygons"
        self.description = "Creates polygons using updated line featureclass"
        self.callfrom_pyt = True
        self.category = 'Elevation derived hydrography'

    def getParameterInfo(self):
        """
        Define the parameters for use in arcmap/pro.
        """
        params = [wbd_params.linefc_updated,
                  wbd_params.wbdpolygon_labelpnt]
        return params

    def updateMessages(self, params):
        """
        Modify the messages created by internal validation for each tool
        parameter.This method is called after internal validation. 
        """
        message = 'Can only enter label points for HUC2, HUC4, HUC6, HUC8, HUC10, HUC12, HUC14, or HUC16 featureclasses.'
        if params[1].altered and params[1].value:
            labelpnts = [os.path.basename(x) for x in params[1].valueAsText.split(';')]
            _, hudigit_list = wbd_f.sort_polygons(labelpnts)
            if not hudigit_list:
                params[1].setErrorMessage(message)

    def execute(self, params, messages):
        """
        Creates polygons.
        """
        # parameters
        if self.callfrom_pyt:
            self.linefc_updated = params[0].valueAsText
            self.wbdpolygon_labelpnt = params[1].valueAsText
        else:
            self.linefc_updated = params[0]
            self.wbdpolygon_labelpnt = params[1]
        try:
            self.wbdpolygon_labelpnt = self.wbdpolygon_labelpnt.split(';')
        except AttributeError:
            pass
        LINE_FPATH = wbd_f.get_fpath(self.linefc_updated)
        self.folder = os.path.dirname(LINE_FPATH)
        self.polygons = []
        create_topology = True
        self.wbdpolygon_labelpnt, hudigits = wbd_f.sort_polygons(self.wbdpolygon_labelpnt)
        for i, fc in enumerate(self.wbdpolygon_labelpnt):
            with arcpy.EnvManager(overwriteOutput=True):
                digit = hudigits[i]
                fname = 'WBDHU' + digit
                if arcpy.Exists(os.path.join(self.folder, fname)):
                    arcpy.AddWarning('{} already exists: polygons not created.'.format(os.path.join(self.folder, fname)))
                    create_topology = False
                else:
                    template = template_dict[digit]
                    new_polygons = arcpy.CreateFeatureclass_management(
                        self.folder,
                        fname,
                        template=template
                    )
                    where = """ {} <= {} """.format(arcpy.AddFieldDelimiters(self.linefc_updated, wbd_c.F_HUDIGIT), digit)
                    line_fl = arcpy.MakeFeatureLayer_management(self.linefc_updated, 'line_fl', where_clause=where)
                    temp_polygons = arcpy.FeatureToPolygon_management(
                        line_fl,
                        os.path.join(MEMORY_FPATH, 'polygons'),
                        label_features=fc
                    )
                    arcpy.CalculateField_management(temp_polygons, wbd_c.F_AREACRES, "!SHAPE.AREA@ACRES!", "PYTHON", "")
                    arcpy.CalculateField_management(temp_polygons, wbd_c.F_AREASQKM, "!SHAPE.AREA@SQUAREKILOMETERS!", "PYTHON", "")
                    arcpy.Append_management(temp_polygons, new_polygons, "NO_TEST")
                    if digit in ('10', '12', '14'):
                        self.polygons.append(new_polygons[0])
        # create topology (if in feature dataset)
        if create_topology and '.gdb' in self.folder and not self.folder.endswith('.gdb'):
            self.polygons = sorted(self.polygons)
            createtopology = geometry_createtopology.CreateTopology()
            createtopology.callfrom_pyt = False
            createtopology.execute((LINE_FPATH, self.polygons), None)
        else:
            arcpy.AddWarning('Topology not created.')

if __name__ == '__main__':
    """
    Execute as standalone script.
    """
    updated_lines = r'C:\GIS_Project\WBD\AK\Work\hu19010204_redo\nqc_review19010204_042721.gdb\New_WBD_alb\Line_new'
    labels = [
        # r'C:\GIS_Project\WBD\AK\Work\hu19010204_redo\nqc_review19010204_042721.gdb\New_WBD_alb\hu8new_lblpnt',
        # r'C:\GIS_Project\WBD\AK\Work\hu19010204_redo\nqc_review19010204_042721.gdb\New_WBD_alb\hu10new_lblpnt',
        r'C:\GIS_Project\WBD\AK\Work\hu19010204_redo\nqc_review19010204_042721.gdb\New_WBD_alb\hu12new_lblpnt',
        # r'C:\GIS_Project\WBD\AK\Work\hu19010204_redo\nqc_review19010204_042721.gdb\New_WBD_alb\hu14new_lblpnt'
    ]
    params = (updated_lines, labels)
    createpolygons = CreatePolygons()
    createpolygons.callfrom_pyt = False
    createpolygons.execute(params, None)

