#!/usr/bin/env python3

# Interactive shell for working with SIM / UICC / USIM / ISIM cards
#
# (C) 2021 by Harald Welte <laforge@osmocom.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from typing import List

import json
import traceback

import cmd2
from cmd2 import style, fg, bg
from cmd2 import CommandSet, with_default_category, with_argparser
import argparse

import os
import sys
from pathlib import Path
from io import StringIO

from pySim.ts_51_011 import EF, DF, EF_SST_map
from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map
from pySim.ts_31_103 import EF_IST_map, EF_ISIM_ADF_map

from pySim.exceptions import *
from pySim.commands import SimCardCommands
from pySim.transport import init_reader, ApduTracer, argparse_add_reader_args
from pySim.cards import card_detect, SimCard
from pySim.utils import h2b, swap_nibbles, rpad, b2h, h2s, JsonEncoder, bertlv_parse_one
from pySim.utils import dec_st, sanitize_pin_adm, tabulate_str_list, is_hex, boxed_heading_str
from pySim.card_handler import CardHandler, CardHandlerAuto

from pySim.filesystem import CardMF, RuntimeState, CardDF, CardADF, CardModel
from pySim.ts_51_011 import CardProfileSIM, DF_TELECOM, DF_GSM
from pySim.ts_102_221 import CardProfileUICC
from pySim.ts_31_102 import CardApplicationUSIM
from pySim.ts_31_103 import CardApplicationISIM
from pySim.ara_m import CardApplicationARAM
from pySim.gsm_r import DF_EIRENE

# we need to import this module so that the SysmocomSJA2 sub-class of
# CardModel is created, which will add the ATR-based matching and
# calling of SysmocomSJA2.add_files.  See  CardModel.apply_matching_models
import pySim.sysmocom_sja2

from pySim.card_key_provider import CardKeyProviderCsv, card_key_provider_register, card_key_provider_get_field

def init_card(sl):
	"""
	Detect card in reader and setup card profile and runtime state. This
	function must be called at least once on startup. The card and runtime
	state object (rs) is required for all pySim-shell commands.
	"""

	# Wait up to three seconds for a card in reader and try to detect
	# the card type.
	print("Waiting for card...")
	try:
		sl.wait_for_card(3)
	except NoCardError:
		print("No card detected!")
		return None, None
	except:
		print("Card not readable!")
		return None, None

	card = card_detect("auto", scc)
	if card is None:
		print("Could not detect card type!")
		return None, None

	# Create runtime state with card profile
	profile = CardProfileUICC()
	profile.add_application(CardApplicationUSIM())
	profile.add_application(CardApplicationISIM())
	profile.add_application(CardApplicationARAM())
	rs = RuntimeState(card, profile)

	# FIXME: do this dynamically
	rs.mf.add_file(DF_TELECOM())
	rs.mf.add_file(DF_GSM())
	rs.mf.add_file(DF_EIRENE())

	CardModel.apply_matching_models(scc, rs)

	# inform the transport that we can do context-specific SW interpretation
	sl.set_sw_interpreter(rs)

	return rs, card

class PysimApp(cmd2.Cmd):
	CUSTOM_CATEGORY = 'pySim Commands'
	def __init__(self, card, rs, sl, ch, script = None):
		super().__init__(persistent_history_file='~/.pysim_shell_history', allow_cli_args=False,
				 use_ipython=True, auto_load_commands=False, startup_script=script)
		self.intro = style('Welcome to pySim-shell!', fg=fg.red)
		self.default_category = 'pySim-shell built-in commands'
		self.card = None
		self.rs = None
		self.py_locals = { 'card': self.card, 'rs' : self.rs }
		self.sl = sl
		self.ch = ch

		self.numeric_path = False
		self.add_settable(cmd2.Settable('numeric_path', bool, 'Print File IDs instead of names',
						  onchange_cb=self._onchange_numeric_path))
		self.conserve_write = True
		self.add_settable(cmd2.Settable('conserve_write', bool, 'Read and compare before write',
						  onchange_cb=self._onchange_conserve_write))
		self.json_pretty_print = True
		self.add_settable(cmd2.Settable('json_pretty_print', bool, 'Pretty-Print JSON output'))
		self.apdu_trace = False
		self.add_settable(cmd2.Settable('apdu_trace', bool, 'Trace and display APDUs exchanged with card',
						  onchange_cb=self._onchange_apdu_trace))

		self.equip(card, rs)

	def equip(self, card, rs):
		"""
		Equip pySim-shell with the supplied card and runtime state, add (or remove) all required settables and
		and commands to enable card operations.
		"""

		rc = False

		# Unequip everything from pySim-shell that would not work in unequipped state
		if self.rs:
			self.rs.unregister_cmds(self)
		for cmds in [Iso7816Commands, PySimCommands]:
			cmd_set = self.find_commandsets(cmds)
			if cmd_set:
				self.unregister_command_set(cmd_set[0])

		self.card = card
		self.rs = rs

		# When a card object and a runtime state is present, (re)equip pySim-shell with everything that is
		# needed to operate on cards.
		if self.card and self.rs:
			self._onchange_conserve_write('conserve_write', False, self.conserve_write)
			self._onchange_apdu_trace('apdu_trace', False, self.apdu_trace)
			self.register_command_set(Iso7816Commands())
			self.register_command_set(PySimCommands())
			self.iccid, sw = self.card.read_iccid()
			rs.select('MF', self)
			rc = True
		else:
			self.poutput("pySim-shell not equipped!")

		self.update_prompt()
		return rc

	def poutput_json(self, data, force_no_pretty = False):
		"""like cmd2.poutput() but for a JSON serializable dict."""
		if force_no_pretty or self.json_pretty_print == False:
			output = json.dumps(data, cls=JsonEncoder)
		else:
			output = json.dumps(data, cls=JsonEncoder, indent=4)
		self.poutput(output)

	def _onchange_numeric_path(self, param_name, old, new):
		self.update_prompt()

	def _onchange_conserve_write(self, param_name, old, new):
		if self.rs:
			self.rs.conserve_write = new

	def _onchange_apdu_trace(self, param_name, old, new):
		if self.card:
			if new == True:
				self.card._scc._tp.apdu_tracer = self.Cmd2ApduTracer(self)
			else:
				self.card._scc._tp.apdu_tracer = None

	class Cmd2ApduTracer(ApduTracer):
		def __init__(self, cmd2_app):
			self.cmd2 = app

		def trace_response(self, cmd, sw, resp):
			self.cmd2.poutput("-> %s %s" % (cmd[:10], cmd[10:]))
			self.cmd2.poutput("<- %s: %s" % (sw, resp))

	def update_prompt(self):
		if self.rs:
			path_list = self.rs.selected_file.fully_qualified_path(not self.numeric_path)
			self.prompt = 'pySIM-shell (%s)> ' % ('/'.join(path_list))
		else:
			self.prompt = 'pySIM-shell (no card)> '

	@cmd2.with_category(CUSTOM_CATEGORY)
	def do_intro(self, _):
		"""Display the intro banner"""
		self.poutput(self.intro)

	def do_eof(self, _: argparse.Namespace) -> bool:
		self.poutput("")
		return self.do_quit('')

	@cmd2.with_category(CUSTOM_CATEGORY)
	def do_equip(self, opts):
		"""Equip pySim-shell with card"""
		rs, card = init_card(sl)
		self.equip(card, rs)

	class InterceptStderr(list):
		def __init__(self):
			self._stderr_backup = sys.stderr
		def __enter__(self):
			self._stringio_stderr = StringIO()
			sys.stderr = self._stringio_stderr
			return self
		def __exit__(self, *args):
			self.stderr = self._stringio_stderr.getvalue().strip()
			del self._stringio_stderr
			sys.stderr = self._stderr_backup

	def _show_failure_sign(self):
		self.poutput(style("  +-------------+", fg=fg.bright_red))
		self.poutput(style("  +   ##   ##   +", fg=fg.bright_red))
		self.poutput(style("  +    ## ##    +", fg=fg.bright_red))
		self.poutput(style("  +     ###     +", fg=fg.bright_red))
		self.poutput(style("  +    ## ##    +", fg=fg.bright_red))
		self.poutput(style("  +   ##   ##   +", fg=fg.bright_red))
		self.poutput(style("  +-------------+", fg=fg.bright_red))
		self.poutput("")

	def _show_success_sign(self):
		self.poutput(style("  +-------------+", fg=fg.bright_green))
		self.poutput(style("  +          ## +", fg=fg.bright_green))
		self.poutput(style("  +         ##  +", fg=fg.bright_green))
		self.poutput(style("  +  #    ##    +", fg=fg.bright_green))
		self.poutput(style("  +   ## #      +", fg=fg.bright_green))
		self.poutput(style("  +    ##       +", fg=fg.bright_green))
		self.poutput(style("  +-------------+", fg=fg.bright_green))
		self.poutput("")

	def _process_card(self, first, script_path):

		# Early phase of card initialzation (this part may fail with an exception)
		try:
			rs, card = init_card(self.sl)
			rc = self.equip(card, rs)
		except:
			self.poutput("")
			self.poutput("Card initialization failed with an exception:")
			self.poutput("---------------------8<---------------------")
			traceback.print_exc()
			self.poutput("---------------------8<---------------------")
			self.poutput("")
			return -1

		# Actual card processing step. This part should never fail with an exception since the cmd2
		# do_run_script method will catch any exception that might occur during script execution.
		if rc:
			self.poutput("")
			self.poutput("Transcript stdout:")
			self.poutput("---------------------8<---------------------")
			with self.InterceptStderr() as logged:
				self.do_run_script(script_path)
			self.poutput("---------------------8<---------------------")

			self.poutput("")
			self.poutput("Transcript stderr:")
			if logged.stderr:
				self.poutput("---------------------8<---------------------")
				self.poutput(logged.stderr)
				self.poutput("---------------------8<---------------------")
			else:
				self.poutput("(none)")

			# Check for exceptions
			self.poutput("")
			if "EXCEPTION of type" not in logged.stderr:
				return 0

		return -1

	bulk_script_parser = argparse.ArgumentParser()
	bulk_script_parser.add_argument('script_path', help="path to the script file")
	bulk_script_parser.add_argument('--halt_on_error', help='stop card handling if an exeption occurs',
					action='store_true')
	bulk_script_parser.add_argument('--tries', type=int, default=2,
					help='how many tries before trying the next card')
	bulk_script_parser.add_argument('--on_stop_action', type=str, default=None,
					help='commandline to execute when card handling has stopped')
	bulk_script_parser.add_argument('--pre_card_action', type=str, default=None,
					help='commandline to execute before actually talking to the card')

	@cmd2.with_argparser(bulk_script_parser)
	@cmd2.with_category(CUSTOM_CATEGORY)
	def do_bulk_script(self, opts):
		"""Run script on multiple cards (bulk provisioning)"""

		# Make sure that the script file exists and that it is readable.
		if not os.access(opts.script_path, os.R_OK):
			self.poutput("Invalid script file!")
			return

		success_count = 0
		fail_count = 0

		first = True
		while 1:
			# TODO: Count consecutive failures, if more than N consecutive failures occur, then stop.
			# The ratinale is: There may be a problem with the device, we do want to prevent that
			# all remaining cards are fired to the error bin. This is only relevant for situations
			# with large stacks, probably we do not need this feature right now.

			try:
				# In case of failure, try multiple times.
				for i in range(opts.tries):
					# fetch card into reader bay
					ch.get(first)

					# if necessary execute an action before we start processing the card
					if(opts.pre_card_action):
						os.system(opts.pre_card_action)

					# process the card
					rc = self._process_card(first, opts.script_path)
					if rc == 0:
						success_count = success_count + 1
						self._show_success_sign()
						self.poutput("Statistics: success :%i, failure: %i" % (success_count, fail_count))
						break
					else:
						fail_count = fail_count + 1
						self._show_failure_sign()
						self.poutput("Statistics: success :%i, failure: %i" % (success_count, fail_count))


				# Depending on success or failure, the card goes either in the "error" bin or in the
				# "done" bin.
				if rc < 0:
					ch.error()
				else:
					ch.done()

				# In most cases it is possible to proceed with the next card, but the
				# user may decide to halt immediately when an error occurs
				if opts.halt_on_error and rc < 0:
					return

			except (KeyboardInterrupt):
				self.poutput("")
				self.poutput("Terminated by user!")
				return
			except (SystemExit):
				# When all cards are processed the card handler device will throw a SystemExit
				# exception. Also Errors that are not recoverable (cards stuck etc.) will end up here.
				# The user has the option to execute some action to make aware that the card handler
				# needs service.
				if(opts.on_stop_action):
					os.system(opts.on_stop_action)
				return
			except:
				self.poutput("")
				self.poutput("Card handling failed with an exception:")
				self.poutput("---------------------8<---------------------")
				traceback.print_exc()
				self.poutput("---------------------8<---------------------")
				self.poutput("")
				fail_count = fail_count + 1
				self._show_failure_sign()
				self.poutput("Statistics: success :%i, failure: %i" % (success_count, fail_count))

			first = False

	echo_parser = argparse.ArgumentParser()
	echo_parser.add_argument('string', help="string to echo on the shell")

	@cmd2.with_argparser(echo_parser)
	@cmd2.with_category(CUSTOM_CATEGORY)
	def do_echo(self, opts):
		"""Echo (print) a string on the console"""
		self.poutput(opts.string)

@with_default_category('pySim Commands')
class PySimCommands(CommandSet):
	def __init__(self):
		super().__init__()

	dir_parser = argparse.ArgumentParser()
	dir_parser.add_argument('--fids', help='Show file identifiers', action='store_true')
	dir_parser.add_argument('--names', help='Show file names', action='store_true')
	dir_parser.add_argument('--apps', help='Show applications', action='store_true')
	dir_parser.add_argument('--all', help='Show all selectable identifiers and names', action='store_true')

	@cmd2.with_argparser(dir_parser)
	def do_dir(self, opts):
		"""Show a listing of files available in currently selected DF or MF"""
		if opts.all:
			flags = []
		elif opts.fids or opts.names or opts.apps:
			flags = ['PARENT', 'SELF']
			if opts.fids:
				flags += ['FIDS', 'AIDS']
			if opts.names:
				flags += ['FNAMES', 'ANAMES']
			if opts.apps:
				flags += ['ANAMES', 'AIDS']
		else:
			flags = ['PARENT', 'SELF', 'FNAMES', 'ANAMES']
		selectables = list(self._cmd.rs.selected_file.get_selectable_names(flags = flags))
		directory_str = tabulate_str_list(selectables, width = 79, hspace = 2, lspace = 1, align_left = True)
		path_list = self._cmd.rs.selected_file.fully_qualified_path(True)
		self._cmd.poutput('/'.join(path_list))
		path_list = self._cmd.rs.selected_file.fully_qualified_path(False)
		self._cmd.poutput('/'.join(path_list))
		self._cmd.poutput(directory_str)
		self._cmd.poutput("%d files" % len(selectables))

	def walk(self, indent = 0, action = None, context = None):
		"""Recursively walk through the file system, starting at the currently selected DF"""
		files = self._cmd.rs.selected_file.get_selectables(flags = ['FNAMES', 'ANAMES'])
		for f in files:
			if not action:
				output_str = "  " * indent + str(f) + (" " * 250)
				output_str = output_str[0:25]
				if isinstance(files[f], CardADF):
					output_str += " " + str(files[f].aid)
				else:
					output_str += " " + str(files[f].fid)
				output_str += " " + str(files[f].desc)
				self._cmd.poutput(output_str)

			if isinstance(files[f], CardDF):
				skip_df=False
				try:
					fcp_dec = self._cmd.rs.select(f, self._cmd)
				except Exception as e:
					skip_df=True
					df = self._cmd.rs.selected_file
					df_path_list = df.fully_qualified_path(True)
					df_skip_reason_str = '/'.join(df_path_list) + "/" + str(f) + ", " + str(e)
					if context:
						context['DF_SKIP'] += 1
						context['DF_SKIP_REASON'].append(df_skip_reason_str)

				# If the DF was skipped, we never have entered the directory
				# below, so we must not move up.
				if skip_df == False:
					self.walk(indent + 1, action, context)
					fcp_dec = self._cmd.rs.select("..", self._cmd)

			elif action:
				df_before_action = self._cmd.rs.selected_file
				action(f, context)
				# When walking through the file system tree the action must not
				# always restore the currently selected file to the file that
				# was selected before executing the action() callback.
				if df_before_action != self._cmd.rs.selected_file:
					raise RuntimeError("inconsistent walk, %s is currently selected but expecting %s to be selected"
							   % (str(self._cmd.rs.selected_file), str(df_before_action)))

	def do_tree(self, opts):
		"""Display a filesystem-tree with all selectable files"""
		self.walk()

	def export(self, filename, context):
		""" Select and export a single file """
		context['COUNT'] += 1
		df = self._cmd.rs.selected_file

		if not isinstance(df, CardDF):
			raise RuntimeError("currently selected file %s is not a DF or ADF" % str(df))

		df_path_list = df.fully_qualified_path(True)
		df_path_list_fid = df.fully_qualified_path(False)

		file_str = '/'.join(df_path_list) + "/" + str(filename)
		self._cmd.poutput(boxed_heading_str(file_str))

		self._cmd.poutput("# directory: %s (%s)" % ('/'.join(df_path_list), '/'.join(df_path_list_fid)))
		try:
			fcp_dec = self._cmd.rs.select(filename, self._cmd)
			self._cmd.poutput("# file: %s (%s)" % (self._cmd.rs.selected_file.name, self._cmd.rs.selected_file.fid))

			fd = fcp_dec['file_descriptor']
			structure = fd['structure']
			self._cmd.poutput("# structure: %s" % str(structure))

			for f in df_path_list:
				self._cmd.poutput("select " + str(f))
			self._cmd.poutput("select " + self._cmd.rs.selected_file.name)

			if structure == 'transparent':
				result = self._cmd.rs.read_binary()
				self._cmd.poutput("update_binary " + str(result[0]))
			elif structure == 'cyclic' or structure == 'linear_fixed':
				num_of_rec = fd['num_of_rec']
				for r in range(1, num_of_rec + 1):
					result = self._cmd.rs.read_record(r)
					self._cmd.poutput("update_record %d %s" % (r, str(result[0])))
			elif structure == 'ber_tlv':
				tags = self._cmd.rs.retrieve_tags()
				for t in tags:
					result = self._cmd.rs.retrieve_data(t)
					(tag, l, val, remainer) = bertlv_parse_one(h2b(result[0]))
					self._cmd.poutput("set_data 0x%02x %s" % (t, b2h(val)))
			else:
				raise RuntimeError('Unsupported structure "%s" of file "%s"' % (structure, filename))
		except Exception as e:
			bad_file_str = '/'.join(df_path_list) + "/" + str(filename) + ", " + str(e)
			self._cmd.poutput("# bad file: %s" % bad_file_str)
			context['ERR'] += 1
			context['BAD'].append(bad_file_str)

		# When reading the file is done, make sure the parent file is
		# selected again. This will be the usual case, however we need
		# to check before since we must not select the same DF twice
		if df != self._cmd.rs.selected_file:
			self._cmd.rs.select(df.fid or df.aid, self._cmd)

		self._cmd.poutput("#")

	export_parser = argparse.ArgumentParser()
	export_parser.add_argument('--filename', type=str, default=None, help='only export specific file')

	@cmd2.with_argparser(export_parser)
	def do_export(self, opts):
		"""Export files to script that can be imported back later"""
		context = {'ERR':0, 'COUNT':0, 'BAD':[], 'DF_SKIP':0, 'DF_SKIP_REASON':[]}
		if opts.filename:
			self.export(opts.filename, context)
		else:
			self.walk(0, self.export, context)

		self._cmd.poutput(boxed_heading_str("Export summary"))

		self._cmd.poutput("# total files visited: %u" % context['COUNT'])
		self._cmd.poutput("# bad files:           %u" % context['ERR'])
		for b in context['BAD']:
			self._cmd.poutput("#  " + b)

		self._cmd.poutput("# skipped dedicated files(s): %u" % context['DF_SKIP'])
		for b in context['DF_SKIP_REASON']:
			self._cmd.poutput("#  " + b)

		if context['ERR'] and context['DF_SKIP']:
			raise RuntimeError("unable to export %i elementary file(s) and %i dedicated file(s)" % (context['ERR'], context['DF_SKIP']))
		elif context['ERR']:
			raise RuntimeError("unable to export %i elementary file(s)" % context['ERR'])
		elif context['DF_SKIP']:
			raise RuntimeError("unable to export %i dedicated files(s)" % context['ERR'])

	def do_reset(self, opts):
		"""Reset the Card."""
		atr = self._cmd.rs.reset(self._cmd)
		self._cmd.poutput('Card ATR: %s' % atr)
		self._cmd.update_prompt()

	def do_desc(self, opts):
		"""Display human readable file description for the currently selected file"""
		desc = self._cmd.rs.selected_file.desc
		if desc:
			self._cmd.poutput(desc)
		else:
			self._cmd.poutput("no description available")

	def do_verify_adm(self, arg):
		"""VERIFY the ADM1 PIN"""
		if arg:
			# use specified ADM-PIN
			pin_adm = sanitize_pin_adm(arg)
		else:
			# try to find an ADM-PIN if none is specified
			result = card_key_provider_get_field('ADM1', key='ICCID', value=self._cmd.iccid)
			pin_adm = sanitize_pin_adm(result)
			if pin_adm:
				self._cmd.poutput("found ADM-PIN '%s' for ICCID '%s'" % (result, self._cmd.iccid))
			else:
				raise ValueError("cannot find ADM-PIN for ICCID '%s'" % (self._cmd.iccid))

		if pin_adm:
			self._cmd.card.verify_adm(h2b(pin_adm))
		else:
			raise ValueError("error: cannot authenticate, no adm-pin!")

@with_default_category('ISO7816 Commands')
class Iso7816Commands(CommandSet):
	def __init__(self):
		super().__init__()

	def do_select(self, opts):
		"""SELECT a File (ADF/DF/EF)"""
		if len(opts.arg_list) == 0:
			path_list = self._cmd.rs.selected_file.fully_qualified_path(True)
			path_list_fid = self._cmd.rs.selected_file.fully_qualified_path(False)
			self._cmd.poutput("currently selected file: " + '/'.join(path_list) + " (" + '/'.join(path_list_fid) + ")")
			return

		path = opts.arg_list[0]
		fcp_dec = self._cmd.rs.select(path, self._cmd)
		self._cmd.update_prompt()
		self._cmd.poutput_json(fcp_dec)

	def complete_select(self, text, line, begidx, endidx) -> List[str]:
		"""Command Line tab completion for SELECT"""
		index_dict = { 1: self._cmd.rs.selected_file.get_selectable_names() }
		return self._cmd.index_based_complete(text, line, begidx, endidx, index_dict=index_dict)

	def get_code(self, code):
		"""Use code either directly or try to get it from external data source"""
		auto = ('PIN1', 'PIN2', 'PUK1', 'PUK2')

		if str(code).upper() not in auto:
			return sanitize_pin_adm(code)

		result = card_key_provider_get_field(str(code), key='ICCID', value=self._cmd.iccid)
		result = sanitize_pin_adm(result)
		if result:
			self._cmd.poutput("found %s '%s' for ICCID '%s'" % (code.upper(), result, self._cmd.iccid))
		else:
			self._cmd.poutput("cannot find %s for ICCID '%s'" % (code.upper(), self._cmd.iccid))
		return result

	verify_chv_parser = argparse.ArgumentParser()
	verify_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)')
	verify_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source')

	@cmd2.with_argparser(verify_chv_parser)
	def do_verify_chv(self, opts):
		"""Verify (authenticate) using specified PIN code"""
		pin = self.get_code(opts.pin_code)
		(data, sw) = self._cmd.card._scc.verify_chv(opts.pin_nr, h2b(pin))
		self._cmd.poutput("CHV verification successful")

	unblock_chv_parser = argparse.ArgumentParser()
	unblock_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PUK Number, 1=PIN1, 2=PIN2 or custom value (decimal)')
	unblock_chv_parser.add_argument('puk_code', type=str, help='PUK code digits \"PUK1\" or \"PUK2\" to get PUK code from external data source')
	unblock_chv_parser.add_argument('new_pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source')

	@cmd2.with_argparser(unblock_chv_parser)
	def do_unblock_chv(self, opts):
		"""Unblock PIN code using specified PUK code"""
		new_pin = self.get_code(opts.new_pin_code)
		puk = self.get_code(opts.puk_code)
		(data, sw) = self._cmd.card._scc.unblock_chv(opts.pin_nr, h2b(puk), h2b(new_pin))
		self._cmd.poutput("CHV unblock successful")

	change_chv_parser = argparse.ArgumentParser()
	change_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PUK Number, 1=PIN1, 2=PIN2 or custom value (decimal)')
	change_chv_parser.add_argument('pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source')
	change_chv_parser.add_argument('new_pin_code', type=str, help='PIN code digits \"PIN1\" or \"PIN2\" to get PIN code from external data source')

	@cmd2.with_argparser(change_chv_parser)
	def do_change_chv(self, opts):
		"""Change PIN code to a new PIN code"""
		new_pin = self.get_code(opts.new_pin_code)
		pin = self.get_code(opts.pin_code)
		(data, sw) = self._cmd.card._scc.change_chv(opts.pin_nr, h2b(pin), h2b(new_pin))
		self._cmd.poutput("CHV change successful")

	disable_chv_parser = argparse.ArgumentParser()
	disable_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)')
	disable_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source')

	@cmd2.with_argparser(disable_chv_parser)
	def do_disable_chv(self, opts):
		"""Disable PIN code using specified PIN code"""
		pin = self.get_code(opts.pin_code)
		(data, sw) = self._cmd.card._scc.disable_chv(opts.pin_nr, h2b(pin))
		self._cmd.poutput("CHV disable successful")

	enable_chv_parser = argparse.ArgumentParser()
	enable_chv_parser.add_argument('--pin-nr', type=int, default=1, help='PIN Number, 1=PIN1, 2=PIN2 or custom value (decimal)')
	enable_chv_parser.add_argument('pin_code', type=str, help='PIN code digits, \"PIN1\" or \"PIN2\" to get PIN code from external data source')

	@cmd2.with_argparser(enable_chv_parser)
	def do_enable_chv(self, opts):
		"""Enable PIN code using specified PIN code"""
		pin = self.get_code(opts.pin_code)
		(data, sw) = self._cmd.card._scc.enable_chv(opts.pin_nr, h2b(pin))
		self._cmd.poutput("CHV enable successful")

	def do_deactivate_file(self, opts):
		"""Deactivate the current EF"""
		(data, sw) = self._cmd.card._scc.deactivate_file()

	def do_activate_file(self, opts):
		"""Activate the specified EF"""
		path = opts.arg_list[0]
		(data, sw) = self._cmd.rs.activate_file(path)

	def complete_activate_file(self, text, line, begidx, endidx) -> List[str]:
		"""Command Line tab completion for ACTIVATE FILE"""
		index_dict = { 1: self._cmd.rs.selected_file.get_selectable_names() }
		return self._cmd.index_based_complete(text, line, begidx, endidx, index_dict=index_dict)

	open_chan_parser = argparse.ArgumentParser()
	open_chan_parser.add_argument('chan_nr', type=int, default=0, help='Channel Number')

	@cmd2.with_argparser(open_chan_parser)
	def do_open_channel(self, opts):
		"""Open a logical channel."""
		(data, sw) = self._cmd.card._scc.manage_channel(mode='open', lchan_nr=opts.chan_nr)

	close_chan_parser = argparse.ArgumentParser()
	close_chan_parser.add_argument('chan_nr', type=int, default=0, help='Channel Number')

	@cmd2.with_argparser(close_chan_parser)
	def do_close_channel(self, opts):
		"""Close a logical channel."""
		(data, sw) = self._cmd.card._scc.manage_channel(mode='close', lchan_nr=opts.chan_nr)

	def do_status(self, opts):
		"""Perform the STATUS command."""
		fcp_dec = self._cmd.rs.status()
		self._cmd.poutput_json(fcp_dec)

	suspend_uicc_parser = argparse.ArgumentParser()
	suspend_uicc_parser.add_argument('--min-duration-secs', type=int, default=60,
									 help='Proposed minimum duration of suspension')
	suspend_uicc_parser.add_argument('--max-duration-secs', type=int, default=24*60*60,
									 help='Proposed maximum duration of suspension')

	# not ISO7816-4 but TS 102 221
	@cmd2.with_argparser(suspend_uicc_parser)
	def do_suspend_uicc(self, opts):
		"""Perform the SUSPEND UICC command. Only supported on some UICC."""
		(duration, token, sw) = self._cmd.card._scc.suspend_uicc(min_len_secs=opts.min_duration_secs,
																 max_len_secs=opts.max_duration_secs)
		self._cmd.poutput('Negotiated Duration: %u secs, Token: %s, SW: %s' % (duration, token, sw))


option_parser = argparse.ArgumentParser(prog='pySim-shell', description='interactive SIM card shell',
                                        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
argparse_add_reader_args(option_parser)

global_group = option_parser.add_argument_group('General Options')
global_group.add_argument('--script', metavar='PATH', default=None,
                          help='script with pySim-shell commands to be executed automatically at start-up')
global_group.add_argument('--csv', metavar='FILE', default=None, help='Read card data from CSV file')
global_group.add_argument("--card_handler", dest="card_handler_config", metavar="FILE",
			  help="Use automatic card handling machine")

adm_group = global_group.add_mutually_exclusive_group()
adm_group.add_argument('-a', '--pin-adm', metavar='PIN_ADM1', dest='pin_adm', default=None,
                       help='ADM PIN used for provisioning (overwrites default)')
adm_group.add_argument('-A', '--pin-adm-hex', metavar='PIN_ADM1_HEX', dest='pin_adm_hex', default=None,
                       help='ADM PIN used for provisioning, as hex string (16 characters long)')


if __name__ == '__main__':

	# Parse options
	opts = option_parser.parse_args()

	# If a script file is specified, be sure that it actually exists
	if opts.script:
		if not os.access(opts.script, os.R_OK):
			print("Invalid script file!")
			sys.exit(2)

	# Register csv-file as card data provider, either from specified CSV
	# or from CSV file in home directory
	csv_default = str(Path.home()) + "/.osmocom/pysim/card_data.csv"
	if opts.csv:
		card_key_provider_register(CardKeyProviderCsv(opts.csv))
	if os.path.isfile(csv_default):
		card_key_provider_register(CardKeyProviderCsv(csv_default))

	# Init card reader driver
	sl = init_reader(opts)
	if sl is None:
		exit(1)

	# Create command layer
	scc = SimCardCommands(transport=sl)

	# Create a card handler (for bulk provisioning)
	if opts.card_handler_config:
		ch = CardHandlerAuto(None, opts.card_handler_config)
	else:
		ch = CardHandler(sl)

	# Detect and initialize the card in the reader. This may fail when there
	# is no card in the reader or the card is unresponsive. PysimApp is
	# able to tolerate and recover from that.
	try:
		rs, card = init_card(sl)
		app = PysimApp(card, rs, sl, ch, opts.script)
	except:
		print("Card initialization failed with an exception:")
		print("---------------------8<---------------------")
		traceback.print_exc()
		print("---------------------8<---------------------")
		print("(you may still try to recover from this manually by using the 'equip' command.)")
		print(" it should also be noted that some readers may behave strangely when no card")
		print(" is inserted.)")
		print("")
		app = PysimApp(None, None, sl, ch, opts.script)

	# If the user supplies an ADM PIN at via commandline args authenticate
	# immediately so that the user does not have to use the shell commands
	pin_adm = sanitize_pin_adm(opts.pin_adm, opts.pin_adm_hex)
	if pin_adm:
		if not card:
			print("Card error, cannot do ADM verification with supplied ADM pin now.")
		try:
			card.verify_adm(h2b(pin_adm))
		except Exception as e:
			print(e)

	app.cmdloop()
