"""An output module that writes event with geography data to a KML XML file.

The Keyhole Markup Language (KML) is an XML notation for expressing geographic
annotation and visualization within Internet-based, two-dimensional maps and
three-dimensional Earth browsers.
"""

import codecs

from xml.etree import ElementTree

from plaso.output import manager
from plaso.output import rawpy


class KMLOutputModule(rawpy.NativePythonOutputModule):
  """Output module for a Keyhole Markup Language (KML) XML file."""

  NAME = 'kml'
  DESCRIPTION = 'Saves events with geography data into a KML format.'

  def WriteFieldValues(self, output_mediator, field_values):
    """Writes field values to the output.

    Args:
      output_mediator (OutputMediator): mediates interactions between output
          modules and other components, such as storage and dfVFS.
      field_values (dict[str, str]): output field values per name.
    """
    latitude = field_values.get('latitude')
    longitude = field_values.get('longitude')
    if None in (latitude, longitude):
      return

    # TODO: make description_text KML values.
    description_text = self._GetString(field_values)

    placemark_xml_element = ElementTree.Element('Placemark')

    name_xml_element = ElementTree.SubElement(placemark_xml_element, 'name')
    name_xml_element.text = field_values['_event_identifier']

    description_xml_element = ElementTree.SubElement(
        placemark_xml_element, 'description')
    description_xml_element.text = f'{description_text:s}\n'

    point_xml_element = ElementTree.SubElement(placemark_xml_element, 'Point')

    coordinates_xml_element = ElementTree.SubElement(
        point_xml_element, 'coordinates')
    coordinates_xml_element.text = f'{longitude!s},{latitude!s}'

    # Note that ElementTree.tostring() will appropriately escape the input data.
    output_text = ElementTree.tostring(placemark_xml_element)

    output_text = codecs.decode(output_text, output_mediator.encoding)

    self.WriteText(output_text)

  def WriteFooter(self):
    """Writes the footer to the output."""
    self.WriteText('</Document></kml>')

  def WriteHeader(self, output_mediator):
    """Writes the header to the output.

    Args:
      output_mediator (OutputMediator): mediates interactions between output
          modules and other components, such as storage and dfVFS.
    """
    self.WriteText((
        f'<?xml version="1.0" encoding="{output_mediator.encoding:s}"?>'
        f'<kml xmlns="http://www.opengis.net/kml/2.2"><Document>'))


manager.OutputManager.RegisterOutput(KMLOutputModule)
