#!/usr/bin/env python

from __future__ import print_function

from clarifai.errors import ApiError
from clarifai.rest import ApiClient, TokenError, ClarifaiApp

"""
the clarifai command line utility

Basically it helps to setup the environmental variables for the API Clients
"""

import os
import sys
import platform
from pprint import pprint
from configparser import ConfigParser
from builtins import input
from subprocess import call


def configure():
  """ configure the CLARIFAI_API_KEY environmental variable
  """

  conf_file = _conf_file()

  api_key = ''
  if os.environ.get('CLARIFAI_API_KEY'):
    print('The environment variable CLARIFAI_API_KEY is already set. ')
    api_key = os.environ['CLARIFAI_API_KEY']
  elif os.path.exists(conf_file):
    parser = ConfigParser()
    parser.optionxform = str

    with open(conf_file, 'r') as fdr:
      parser.readfp(fdr)

    if parser.has_option('clarifai', 'CLARIFAI_API_KEY'):
      api_key = parser.get('clarifai', 'CLARIFAI_API_KEY')

  api_key_input = input('CLARIFAI_API_KEY: [%s]: ' % _masked_api_key(api_key))
  if api_key_input:
    _setup(api_key_input)
  elif api_key:
    _setup(api_key)

  try:
    app = ClarifaiApp()
    app.api.get_inputs(1, 1)
    print('\nCLARIFAI_API_KEY is valid')
    print('Saved it to environment and to ~/.clarifai/config')
  except ApiError:
    print('Invalid CLARIFAI_API_KEY, please try again')


def _setup(api_key):
  """ write back CLARIFAI_API_KEY to config file
      config file is at ~/.clarifai/config
  """

  os.environ['CLARIFAI_API_KEY'] = api_key

  conf_file = _conf_file()

  parser = ConfigParser()
  parser.optionxform = str

  if os.path.exists(conf_file):
    parser.readfp(open(conf_file, 'r'))

  if not parser.has_section('clarifai'):
    parser.add_section('clarifai')

  # Remove deprecated CLARIFAI_APP_ID and CLARIFAI_APP_SECRET from the .config file
  if parser.has_option('clarifai', 'CLARIFAI_APP_ID'):
    parser.remove_option('clarifai', 'CLARIFAI_APP_ID')
  if parser.has_option('clarifai', 'CLARIFAI_APP_SECRET'):
    parser.remove_option('clarifai', 'CLARIFAI_APP_SECRET')

  parser.set('clarifai', 'CLARIFAI_API_KEY', api_key)

  with open(conf_file, 'w') as fdw:
    parser.write(fdw)


def _masked_api_key(api_key):
  return (len(api_key) - 4) * '*' + api_key[-4:]


def _conf_file():
  home_dir = os.environ['HOMEPATH'] if platform.system() == 'Windows' else os.environ['HOME']
  conf_dir = os.path.join(home_dir, '.clarifai')
  if not os.path.exists(conf_dir):
    os.mkdir(conf_dir)
  elif not os.path.isdir(conf_dir):
    raise Exception('%s should be a directory, not a file' % conf_dir)
  return os.path.join(conf_dir, 'config')


def diagnose():
  """ diagnose function
      this will print out essential library and system level info
      to facilitate the troubleshooting when issue occurs
  """

  print('Clarifai API Diagnosis Info')
  print('-' * 85)

  print('>>>>> OS Version')
  pprint(platform.system())
  print('')

  print('>>>>> Python Version')
  pprint(sys.version)
  print('')

  print('>>>>> Environmental Variables')
  pprint(os.environ)
  print('')

  print('>>>>> Pip Package Info')
  call(['pip', 'freeze'])
  print('')

  print('>>>>> Clarifai Pip Package Info')
  call(['pip', 'show', '-f', 'clarifai'])
  print('')


def print_help():
  """ show help """

  print("""DESCRIPTION:
    This script helps to set the CLARIFAI_API_KEY environment variable and to diagnose the
    environment in case of troubles

USAGE:
    clarifai help                Show this help text
    clarifai config              Configure the environment
    clarifai diagnose            Diagnose the environment
""")


def main():

  if len(sys.argv) < 2:
    print_help()
    exit()

  command = sys.argv[1]
  if command == 'configure' or command == 'config':
    configure()
  elif command == 'diagnose':
    diagnose()
  else:
    print_help()


if __name__ == '__main__':
  main()

