# -*- coding: utf-8 -*-
"""Utility functions to get a Timesketch API client and an importer client."""
import re
import threading
from typing import Sequence

from timesketch_api_client import client
from timesketch_api_client import config
from timesketch_api_client import crypto

from dftimewolf.lib import cache
from dftimewolf.lib.containers import containers
from dftimewolf.lib.errors import DFTimewolfError

# The name of a ticket attribute that contains the URL to a sketch.
_SKETCH_ATTRIBUTE_NAME = 'Timesketch URL'

LOCK = threading.Lock()


def GetSketchIDFromAttributes(
  attribute_containers: Sequence[containers.TicketAttribute]
) -> int:
  """Attempts to retrieve a Timesketch ID from ticket attributes.

  Args:
    attribute_containers: List of TicketAttribute containers extracted from a
      ticket.

  Returns:
    int: the sketch identifier, or 0 if one was not available.
  """
  for attribute in attribute_containers:
    if attribute.name == _SKETCH_ATTRIBUTE_NAME:
      sketch_match = re.search(r'sketch/(\d+)/', attribute.value)
      if sketch_match:
        sketch_id = int(sketch_match.group(1), 10)
        return sketch_id
  return 0

def GetApiClient(cache_: cache.DFTWCache,
                 token_password: str='') -> client.TimesketchApi:
  """Returns a Timesketch API client using thread safe methods.

  This function either returns an API client that has been stored
  in the cache object, or if not it will read Timesketch RC files
  to configure a Timesketch API client. If the RC file does not exist
  or is missing values questions will be asked to fully configure
  the client.

  Args:
    cache_: recipe cache.
    token_password (str): optional password used to decrypt the
        Timesketch credential storage. Defaults to an empty string since
        the upstream library expects a string value. An empty string means
        a password will be generated by the upstream library.

  Returns:
    object: A timesketch API object (instance of TimesketchApi).

  Raises:
    DFTimewolfError: If the configuration file cannot be modified.
  """
  with LOCK:
    ts_client = cache_.GetFromCache('timesketch_client', default_value=None)
    if ts_client:
      return ts_client

    assistant = config.ConfigAssistant()
    assistant.load_config_file()
    try:
      config.configure_missing_parameters(
          config_assistant=assistant, token_password=token_password)
    except OSError as exception:
      raise DFTimewolfError(
          'Unable to get a Timesketch API Client',
          critical=False) from exception


    ts_client = assistant.get_client(token_password=token_password)

    if not ts_client:
      raise DFTimewolfError(
          'Unable to get a Timesketch API Client', critical=False)

    assistant.save_config()

    if ts_client.credentials:
      cred_storage = crypto.CredentialStorage()
      cred_storage.save_credentials(
          ts_client.credentials, config_assistant=assistant,
          password=token_password)

    cache_.AddToCache('timesketch_client', ts_client)
    return ts_client
