#!/usr/bin/python3
# -*- mode: python -*-
# Generate an xearth database from the LDAP entries
# LDAP entires for lat/long can be in one of 3 different formats
#    1) Decimal Degrees
#        +-DDD.DDDDDDDDDDDDDDD
#    2) Degrees Minutes (DGM), common output from GPS units
#        +-DDDMM.MMMMMMMMMMMMM
#    3) Degrees Minutes Seconds (DGMS)
#        +-DDDMMSS.SSSSSSSSSSS
# Decimal Degrees is the most basic format, but to have good accuracy it
# needs a large number of decimals. The other formats are all derived from it:
#  DGM -> DD   DDD + (MM.MMMMMMMM)/60
#  DGMS -> DD  DDD + (MM + (SS.SSSSSS)/60)/60
# For Latitude + is North, for Longitude + is East

from __future__ import print_function

import getopt
import sys
import pwd
import posix

import ldap

from userdir_ldap.ldap import (
    passwdAccessLDAP, BaseDn, GetAttr, DecDegree, EmailAddress)

Anon = 0

# Main program starts here
User = pwd.getpwuid(posix.getuid())[0]
BindUser = User
(options, arguments) = getopt.getopt(sys.argv[1:], "au:")
for (switch, val) in options:
   if (switch == '-u'):
      User = val
   if (switch == '-a'):
      Anon = 1

# Connect to the ldap server
lc = passwdAccessLDAP(BaseDn, User)

Attrs = lc.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "latitude=*",
                    ["uid", "cn", "mn", "sn", "latitude", "longitude"])

Attrs.sort()

print("Markers file will be written to markers.dat,", end=" ")
sys.stdout.flush()
F = open("markers.dat", "w")
Count = 0
Failed = 0
for x in Attrs:
   if "latitude" not in x[1] or "longitude" not in x[1]:
      continue
   Count = Count + 1
   try:
      if Anon != 0:
         F.write("%8s %8s \"\"\n" % (DecDegree(GetAttr(x, "latitude"), Anon), DecDegree(GetAttr(x, "longitude"), Anon)))
      else:
         F.write("%16s %16s \"%s\" \t# %s\n" % (DecDegree(GetAttr(x, "latitude"), Anon), DecDegree(GetAttr(x, "longitude"), Anon), GetAttr(x, "uid"), EmailAddress(x)))
   except Exception:
      Failed = Failed + 1
      exc_info = sys.exc_info()
      if Anon == 0:
         F.write("# Failed %s => %s: %s\n" % (x[0], exc_info[0], exc_info[1]))
      else:
         F.write("# Failed => %s: %s\n" % (exc_info[0], exc_info[1]))
F.close()
print(Count, "entries,", Failed, "failures.")
