# Path: plenario/utils/ogr2ogr.py
# class OgrError(Exception):
#     def __init__(self, message):
#         Exception.__init__(self, message)
#         self.message = message
# 
# def import_shapefile_to_table(component_path, table_name):
#     """
#     :param component_path: Path to unzipped shapefile components and the shared name of all components. So if folder 
#         contains foo.shp, foo.prj, foo.dbf, then component_path is path/to/dir/foo. foo.shp and foo.prj must be present.
#     :param table_name: Name that we want table to have in the database
#     """
# 
#     args = ['ogr2ogr',
#             '-f', 'PostgreSQL',  # Use the PostgreSQL driver. Documentation here: http://www.gdal.org/drv_pg.html
# 
#             '-lco', 'PRECISION=no',  # Many .dbf files don't obey their precision headers.
#             # So importing as precision-marked types like NUMERIC(width, precision) often fails.
#             # Instead, import as INTEGER, VARCHAR, FLOAT8.
# 
#             '-nlt', 'PROMOTE_TO_MULTI',  # Import all lines and polygons as multilines and multipolygons
#             # We don't know if the source shapefiles will have multi or non-multi geometries,
#             # so we need to import the most inclusive set of types.
#             '-s_srs', component_path + '.prj',  # Derive source SRID from Well Known Text in .prj
#             '-t_srs', 'EPSG:4326',  # Always convert to 4326
#             postgres_connection_arg,
#             component_path + '.shp',  # Point to .shp so that ogr2ogr knows it's importing a Shapefile.
#             '-nln', table_name,  # (n)ew (l)ayer (n)ame. Set the name of the new table.
#             '-lco', 'GEOMETRY_NAME=geom']  # Always name the geometry column 'geom'
# 
#     subprocess.check_output(args)


import os
import shutil
import tempfile
from plenario.utils.ogr2ogr import OgrError, import_shapefile_to_table
        # Extract all shapefile components to a temporary directory.
        # As implemented now, this creates an absolute path traversal vulnerability.
        # https://cwe.mitre.org/data/definitions/36.html
        # Proposed rewrite: just look for the files with the endings you need (.dbf and friends)
        # and use zipfile.extract() to strip path prefixes
        self.unzip_dir = tempfile.mkdtemp()
        self.shapefile_zip.extractall(self.unzip_dir)

        suffixes = []
        # In the new directory,
        # change every component's file prefix to COMPONENT_PREFIX so that we know where to point ogr2ogr.
        for shapefile_name in os.listdir(self.unzip_dir):
            # Assumption: every filename is formatted like name.suffix
            # Will raise IndexError if assumption is not met.
            # Only split on the first dot to handle oddballs like foo.shp.xml
            file_suffix = str.split(shapefile_name, '.', 1)[1]
            suffixes.append(file_suffix)
            normalized_name = "{}.{}".format(Shapefile.COMPONENT_PREFIX, file_suffix)
            os.rename(os.path.join(self.unzip_dir, shapefile_name),
                      os.path.join(self.unzip_dir, normalized_name))

        # Ideally we have a .dbf too, but we can't move on without a shape and a projection.
        if 'shp' not in suffixes or 'prj' not in suffixes:
            raise ShapefileError('Shapefile missing a .shp or .prj component')

        return self

    def insert_in_database(self, table_name):
        component_path = os.path.join(self.unzip_dir, Shapefile.COMPONENT_PREFIX)
        try:

# Path: plenario/utils/ogr2ogr.py
# class OgrError(Exception):
#     def __init__(self, message):
#         Exception.__init__(self, message)
#         self.message = message
# 
# def import_shapefile_to_table(component_path, table_name):
#     """
#     :param component_path: Path to unzipped shapefile components and the shared name of all components. So if folder 
#         contains foo.shp, foo.prj, foo.dbf, then component_path is path/to/dir/foo. foo.shp and foo.prj must be present.
#     :param table_name: Name that we want table to have in the database
#     """
# 
#     args = ['ogr2ogr',
#             '-f', 'PostgreSQL',  # Use the PostgreSQL driver. Documentation here: http://www.gdal.org/drv_pg.html
# 
#             '-lco', 'PRECISION=no',  # Many .dbf files don't obey their precision headers.
#             # So importing as precision-marked types like NUMERIC(width, precision) often fails.
#             # Instead, import as INTEGER, VARCHAR, FLOAT8.
# 
#             '-nlt', 'PROMOTE_TO_MULTI',  # Import all lines and polygons as multilines and multipolygons
#             # We don't know if the source shapefiles will have multi or non-multi geometries,
#             # so we need to import the most inclusive set of types.
#             '-s_srs', component_path + '.prj',  # Derive source SRID from Well Known Text in .prj
#             '-t_srs', 'EPSG:4326',  # Always convert to 4326
#             postgres_connection_arg,
#             component_path + '.shp',  # Point to .shp so that ogr2ogr knows it's importing a Shapefile.
#             '-nln', table_name,  # (n)ew (l)ayer (n)ame. Set the name of the new table.
#             '-lco', 'GEOMETRY_NAME=geom']  # Always name the geometry column 'geom'
# 
#     subprocess.check_output(args)


# Path: plenario/utils/shapefile.py
import os
import shutil
import tempfile
from plenario.utils.ogr2ogr import OgrError, import_shapefile_to_table

        # Extract all shapefile components to a temporary directory.
        # As implemented now, this creates an absolute path traversal vulnerability.
        # https://cwe.mitre.org/data/definitions/36.html
        # Proposed rewrite: just look for the files with the endings you need (.dbf and friends)
        # and use zipfile.extract() to strip path prefixes
        self.unzip_dir = tempfile.mkdtemp()
        self.shapefile_zip.extractall(self.unzip_dir)

        suffixes = []
        # In the new directory,
        # change every component's file prefix to COMPONENT_PREFIX so that we know where to point ogr2ogr.
        for shapefile_name in os.listdir(self.unzip_dir):
            # Assumption: every filename is formatted like name.suffix
            # Will raise IndexError if assumption is not met.
            # Only split on the first dot to handle oddballs like foo.shp.xml
            file_suffix = str.split(shapefile_name, '.', 1)[1]
            suffixes.append(file_suffix)
            normalized_name = "{}.{}".format(Shapefile.COMPONENT_PREFIX, file_suffix)
            os.rename(os.path.join(self.unzip_dir, shapefile_name),
                      os.path.join(self.unzip_dir, normalized_name))

        # Ideally we have a .dbf too, but we can't move on without a shape and a projection.
        if 'shp' not in suffixes or 'prj' not in suffixes:
            raise ShapefileError('Shapefile missing a .shp or .prj component')

        return self

    def insert_in_database(self, table_name):
        component_path = os.path.join(self.unzip_dir, Shapefile.COMPONENT_PREFIX)
        try:

            import_shapefile_to_table(component_path=component_path, table_name=table_name)