#!/usr/bin/python3

#
#   Copyright (C) 2023 Humanitarian OpenstreetMap Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

import logging
import argparse
import xmltodict
import os
import sys
import re
from collections import OrderedDict
from pathlib import Path
from datetime import datetime
from osm_fieldwork.ODKInstance import ODKInstance
import geojson
import json
from geojson import Feature, FeatureCollection, dump
from shapely.geometry import Point
from datetime import datetime


# Instantiate logger
log = logging.getLogger(__name__)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Convert ODK XML instance file to GeoJson"
    )
    parser.add_argument("-v", "--verbose", nargs="?", const="0", help="verbose output")
    parser.add_argument(
        "-i", "--instance", help="The instance file(s) from ODK Collect"
    )
    parser.add_argument("-o","--outfile", default='tmp.geojson', help='The output file for JOSM')
    args = parser.parse_args()

    # if verbose, dump to the termina
    if not args.verbose:
        root = logging.getLogger()
        root.setLevel(logging.DEBUG)

        ch = logging.StreamHandler(sys.stdout)
        ch.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        )
        ch.setFormatter(formatter)
        root.addHandler(ch)

    xmlfiles = list()
    if args.instance.find("*") >= 0:
        toplevel = Path()
        for dir in toplevel.glob(args.instance):
            if dir.is_dir():
                xml = os.listdir(dir)
                # There is always only one XML file per instance
                full = os.path.join(dir, xml[0])
                xmlfiles.append(full)
    else:
        toplevel = Path(args.instance)
        if toplevel.is_dir():
            # There is always only one XML file per instance
            full = os.path.join(toplevel, os.path.basename(toplevel))
            xmlfiles.append(full + ".xml")

    # print(xmlfiles)

    # These are all generated by Collect, and can be ignored
    rows = list()
    features = list()
    for xml in xmlfiles:
        print("Processing instance file: %s" % xml)
        tags = dict()
        #odkxml = ODKInstance()
        #data = odkxml.parse(filespec=xml)
        file = open(xml, "r")
        # Instances are small, read the whole file
        data = file.read(os.path.getsize(xml))
        doc = xmltodict.parse(data)
        # This is pretty ugly. We know that somewhere in the lower level
        # dicts there are GPS coordinates, which luckily are easy to
        # find and should always be a unique field in a feature. While
        # is ugly, it's also way more efficient than looping through
        # levels to find that one value. Plus htis doesn't care what the
        # key is.
        pat = re.compile("[0-9.]* [0-9.-]* [0-9.]* [0-9.]*")
        data = json.dumps(doc)
        gps = re.findall(pat, str(data))
        for coords in gps:
            tmp = coords.split(' ')
            lat = float(tmp[0])
            lon = float(tmp[1])                
            poi = Point(lon, lat)
        features.append(Feature(geometry=poi, properties=doc['data']))
    collection = FeatureCollection(features)

    now = datetime.now()
    timestamp = f"_{now.year}_{now.month}-{now.day}-{now.hour}-{now.minute}"
    outfile = args.instance.replace("*", "") + timestamp + ".geojson"
    json = open(outfile, 'w')
    dump(collection, json)

    print(f"Wrote output file {outfile}")
