"""SQLite parser plugin for Dropbox sync_history database files."""

from dfdatetime import posix_time as dfdatetime_posix_time

from plaso.containers import events
from plaso.parsers import sqlite
from plaso.parsers.sqlite_plugins import interface


class DropboxSyncHistoryEventData(events.EventData):
  """Dropbox Sync History Database event data.

  Attributes:
    event_type (str): the event type
    file_event_type (str): the file event type
    direction (str): the source of the synchronisation event
    file_identifier (str): the Dropbox identifier of the file.
    local_path (str): the local path of the file.
    recorded_time (dfdatetime.DateTimeValues): date and time the log entry
        was recorded.
  """

  DATA_TYPE = 'dropbox:sync_history:entry'

  def __init__(self):
    """Initializes event data."""
    super().__init__(data_type=self.DATA_TYPE)
    self.event_type = None
    self.file_event_type = None
    self.direction = None
    self.file_identifier = None
    self.local_path = None
    self.recorded_time = None


class DropboxSyncDatabasePlugin(interface.SQLitePlugin):
  """SQLite parser plugin for Dropbox sync_history.db database files.

  The Linux sync_history.db database is typically stored in:
  $HOME/.dropbox/instance1/sync_history.db

  The Windows 10 sync_history.db database is typically stored in:
  $HOME/AppData/Local/Dropbox/instance1/sync_history.db
  """

  NAME = 'dropbox'
  DATA_FORMAT = 'Dropbox sync history database (sync_history.db) file'

  REQUIRED_STRUCTURE = {
      'sync_history': frozenset(['timestamp', 'event_type', 'file_event_type',
      'direction', 'file_id', 'local_path'])}

  QUERIES = [
      ('SELECT timestamp, event_type, file_event_type, direction, file_id, '
       'local_path FROM sync_history;',
       'ParseSyncHistoryRow')]

  SCHEMAS = [{
      'sync_history': (
          'CREATE TABLE sync_history (event_type TEXT NOT NULL, file_event_type'
          ' TEXT, direction TEXT, file_id TEXT, local_path TEXT, timestamp '
          'INTEGER NOT NULL, other_user INTEGER')}]

  def _GetDateTimeRowValue(self, query_hash, row, value_name):
    """Retrieves a date and time value from the row.

    Args:
      query_hash (int): hash of the query, that uniquely identifies the query
          that produced the row.
      row (sqlite3.Row): row.
      value_name (str): name of the value.

    Returns:
      dfdatetime.PosixTime: date and time value or None if not available.
    """
    timestamp = self._GetRowValue(query_hash, row, value_name)
    if timestamp is None:
      return None

    return dfdatetime_posix_time.PosixTime(timestamp=timestamp)

  def ParseSyncHistoryRow(self, parser_mediator, query, row, **unused_kwargs):
    """Parses a sync_history row.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfVFS.
      query (str): query that created the row.
      row (sqlite3.Row): row.
    """
    query_hash = hash(query)

    event_data = DropboxSyncHistoryEventData()
    event_data.event_type = self._GetRowValue(query_hash, row, 'event_type')
    event_data.file_event_type = self._GetRowValue(
        query_hash, row, 'file_event_type')
    event_data.direction = self._GetRowValue(query_hash, row, 'direction')
    event_data.file_identifier = self._GetRowValue(query_hash, row, 'file_id')
    event_data.local_path = self._GetRowValue(query_hash, row, 'local_path')
    event_data.recorded_time = self._GetDateTimeRowValue(
        query_hash, row, 'timestamp')

    parser_mediator.ProduceEventData(event_data)


sqlite.SQLiteParser.RegisterPlugin(DropboxSyncDatabasePlugin)
