# -*- coding: utf-8 -*-

""" pySim: SIM Card commands according to ISO 7816-4 and TS 11.11
"""

#
# Copyright (C) 2009-2010  Sylvain Munaut <tnt@246tNt.com>
# Copyright (C) 2010-2021  Harald Welte <laforge@gnumonks.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 construct import *
from pySim.construct import LV
from pySim.utils import rpad, b2h, h2b, sw_match, bertlv_encode_len, Hexstr, h2i, str_sanitize
from pySim.exceptions import SwMatchError

class SimCardCommands(object):
	def __init__(self, transport):
		self._tp = transport
		self.cla_byte = "a0"
		self.sel_ctrl = "0000"

	# Extract a single FCP item from TLV
	def __parse_fcp(self, fcp):
		# see also: ETSI TS 102 221, chapter 11.1.1.3.1 Response for MF,
		# DF or ADF
		from pytlv.TLV import TLV
		tlvparser = TLV(['82', '83', '84', 'a5', '8a', '8b', '8c', '80', 'ab', 'c6', '81', '88'])

		# pytlv is case sensitive!
		fcp = fcp.lower()

		if fcp[0:2] != '62':
			raise ValueError('Tag of the FCP template does not match, expected 62 but got %s'%fcp[0:2])

		# Unfortunately the spec is not very clear if the FCP length is
		# coded as one or two byte vale, so we have to try it out by
		# checking if the length of the remaining TLV string matches
		# what we get in the length field.
		# See also ETSI TS 102 221, chapter 11.1.1.3.0 Base coding.
		exp_tlv_len = int(fcp[2:4], 16)
		if len(fcp[4:]) // 2 == exp_tlv_len:
			skip = 4
		else:
			exp_tlv_len = int(fcp[2:6], 16)
			if len(fcp[4:]) // 2 == exp_tlv_len:
				skip = 6

		# Skip FCP tag and length
		tlv = fcp[skip:]
		return tlvparser.parse(tlv)

	# Tell the length of a record by the card response
	# USIMs respond with an FCP template, which is different
	# from what SIMs responds. See also:
	# USIM: ETSI TS 102 221, chapter 11.1.1.3 Response Data
	# SIM: GSM 11.11, chapter 9.2.1 SELECT
	def __record_len(self, r) -> int:
		if self.sel_ctrl == "0004":
			tlv_parsed = self.__parse_fcp(r[-1])
			file_descriptor = tlv_parsed['82']
			# See also ETSI TS 102 221, chapter 11.1.1.4.3 File Descriptor
			return int(file_descriptor[4:8], 16)
		else:
			return int(r[-1][28:30], 16)

	# Tell the length of a binary file. See also comment
	# above.
	def __len(self, r) -> int:
		if self.sel_ctrl == "0004":
			tlv_parsed = self.__parse_fcp(r[-1])
			return int(tlv_parsed['80'], 16)
		else:
			return int(r[-1][4:8], 16)

	def get_atr(self) -> str:
		"""Return the ATR of the currently inserted card."""
		return self._tp.get_atr()

	def try_select_path(self, dir_list):
		""" Try to select a specified path

		Args:
			dir_list : list of hex-string FIDs
		"""

		rv = []
		if type(dir_list) is not list:
			dir_list = [dir_list]
		for i in dir_list:
			data, sw = self._tp.send_apdu(self.cla_byte + "a4" + self.sel_ctrl + "02" + i)
			rv.append((data, sw))
			if sw != '9000':
				return rv
		return rv

	def select_path(self, dir_list):
		"""Execute SELECT for an entire list/path of FIDs.

		Args:
			dir_list: list of FIDs representing the path to select

		Returns:
			list of return values (FCP in hex encoding) for each element of the path
		"""
		rv = []
		if type(dir_list) is not list:
			dir_list = [dir_list]
		for i in dir_list:
			data, sw = self.select_file(i)
			rv.append(data)
		return rv

	def select_file(self, fid:str):
		"""Execute SELECT a given file by FID.

		Args:
			fid : file identifier as hex string
		"""

		return self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + fid)

	def select_adf(self, aid:str):
		"""Execute SELECT a given Applicaiton ADF.

		Args:
			aid : application identifier as hex string
		"""

		aidlen = ("0" + format(len(aid) // 2, 'x'))[-2:]
		return self._tp.send_apdu_checksw(self.cla_byte + "a4" + "0404" + aidlen + aid)

	def read_binary(self, ef, length:int=None, offset:int=0):
		"""Execute READD BINARY.

		Args:
			ef : string or list of strings indicating name or path of transparent EF
			length : number of bytes to read
			offset : byte offset in file from which to start reading
		"""
		r = self.select_path(ef)
		if len(r[-1]) == 0:
			return (None, None)
		if length is None:
			length = self.__len(r) - offset
		total_data = ''
		chunk_offset = 0
		while chunk_offset < length:
			chunk_len = min(255, length-chunk_offset)
			pdu = self.cla_byte + 'b0%04x%02x' % (offset + chunk_offset, chunk_len)
			try:
				data, sw = self._tp.send_apdu_checksw(pdu)
			except Exception as e:
				raise ValueError('%s, failed to read (offset %d)' % (str_sanitize(str(e)), offset))
			total_data += data
			chunk_offset += chunk_len
		return total_data, sw

	def update_binary(self, ef, data:str, offset:int=0, verify:bool=False, conserve:bool=False):
		"""Execute UPDATE BINARY.

		Args:
			ef : string or list of strings indicating name or path of transparent EF
			data : hex string of data to be written
			offset : byte offset in file from which to start writing
			verify : Whether or not to verify data after write
		"""
		data_length = len(data) // 2

		# Save write cycles by reading+comparing before write
		if conserve:
			data_current, sw = self.read_binary(ef, data_length, offset)
			if data_current == data:
				return None, sw

		self.select_path(ef)
		total_data = ''
		chunk_offset = 0
		while chunk_offset < data_length:
			chunk_len = min(255, data_length - chunk_offset)
			# chunk_offset is bytes, but data slicing is hex chars, so we need to multiply by 2
			pdu = self.cla_byte + 'd6%04x%02x' % (offset + chunk_offset, chunk_len) + data[chunk_offset*2 : (chunk_offset+chunk_len)*2]
			try:
				chunk_data, chunk_sw = self._tp.send_apdu_checksw(pdu)
			except Exception as e:
				raise ValueError('%s, failed to write chunk (chunk_offset %d, chunk_len %d)' % \
						 (str_sanitize(str(e)), chunk_offset, chunk_len))
			total_data += data
			chunk_offset += chunk_len
		if verify:
			self.verify_binary(ef, data, offset)
		return total_data, chunk_sw

	def verify_binary(self, ef, data:str, offset:int=0):
		"""Verify contents of transparent EF.

		Args:
			ef : string or list of strings indicating name or path of transparent EF
			data : hex string of expected data
			offset : byte offset in file from which to start verifying
		"""
		res = self.read_binary(ef, len(data) // 2, offset)
		if res[0].lower() != data.lower():
			raise ValueError('Binary verification failed (expected %s, got %s)' % (data.lower(), res[0].lower()))

	def read_record(self, ef, rec_no:int):
		"""Execute READ RECORD.

		Args:
			ef : string or list of strings indicating name or path of linear fixed EF
			rec_no : record number to read
		"""
		r = self.select_path(ef)
		rec_length = self.__record_len(r)
		pdu = self.cla_byte + 'b2%02x04%02x' % (rec_no, rec_length)
		return self._tp.send_apdu(pdu)

	def update_record(self, ef, rec_no:int, data:str, force_len:bool=False, verify:bool=False,
					  conserve:bool=False):
		"""Execute UPDATE RECORD.

		Args:
			ef : string or list of strings indicating name or path of linear fixed EF
			rec_no : record number to read
			data : hex string of data to be written
			force_len : enforce record length by using the actual data length
			verify : verify data by re-reading the record
			conserve : read record and compare it with data, skip write on match
		"""
		res = self.select_path(ef)

		if force_len:
			# enforce the record length by the actual length of the given data input
			rec_length = len(data) // 2
		else:
			# determine the record length from the select response of the file and pad
			# the input data with 0xFF if necessary. In cases where the input data
			# exceed we throw an exception.
			rec_length = self.__record_len(res)
			if (len(data) // 2 > rec_length):
				raise ValueError('Data length exceeds record length (expected max %d, got %d)' % (rec_length, len(data) // 2))
			elif (len(data) // 2 < rec_length):
				data = rpad(data, rec_length * 2)

		# Save write cycles by reading+comparing before write
		if conserve:
			data_current, sw = self.read_record(ef, rec_no)
			data_current = data_current[0:rec_length*2]
			if data_current == data:
				return None, sw

		pdu = (self.cla_byte + 'dc%02x04%02x' % (rec_no, rec_length)) + data
		res = self._tp.send_apdu_checksw(pdu)
		if verify:
			self.verify_record(ef, rec_no, data)
		return res

	def verify_record(self, ef, rec_no:int, data:str):
		"""Verify record against given data

		Args:
			ef : string or list of strings indicating name or path of linear fixed EF
			rec_no : record number to read
			data : hex string of data to be verified
		"""
		res = self.read_record(ef, rec_no)
		if res[0].lower() != data.lower():
			raise ValueError('Record verification failed (expected %s, got %s)' % (data.lower(), res[0].lower()))

	def record_size(self, ef):
		"""Determine the record size of given file.

		Args:
			ef : string or list of strings indicating name or path of linear fixed EF
		"""
		r = self.select_path(ef)
		return self.__record_len(r)

	def record_count(self, ef):
		"""Determine the number of records in given file.

		Args:
			ef : string or list of strings indicating name or path of linear fixed EF
		"""
		r = self.select_path(ef)
		return self.__len(r) // self.__record_len(r)

	def binary_size(self, ef):
		"""Determine the size of given transparent file.

		Args:
			ef : string or list of strings indicating name or path of transparent EF
		"""
		r = self.select_path(ef)
		return self.__len(r)

	# TS 102 221 Section 11.3.1 low-level helper
	def _retrieve_data(self, tag:int, first:bool=True):
		if first:
			pdu = '80cb008001%02x' % (tag)
		else:
			pdu = '80cb000000'
		return self._tp.send_apdu_checksw(pdu)

	def retrieve_data(self, ef, tag:int):
		"""Execute RETRIEVE DATA, see also TS 102 221 Section 11.3.1.

		Args
			ef : string or list of strings indicating name or path of transparent EF
			tag : BER-TLV Tag of value to be retrieved
		"""
		r = self.select_path(ef)
		if len(r[-1]) == 0:
			return (None, None)
		total_data = ''
		# retrieve first block
		data, sw = self._retrieve_data(tag, first=True)
		total_data += data
		while sw == '62f1' or sw == '62f2':
			data, sw = self._retrieve_data(tag, first=False)
			total_data += data
		return total_data, sw

	# TS 102 221 Section 11.3.2 low-level helper
	def _set_data(self, data:str, first:bool=True):
		if first:
			p1 = 0x80
		else:
			p1 = 0x00
		if isinstance(data, bytes) or isinstance(data, bytearray):
			data = b2h(data)
		pdu = '80db00%02x%02x%s' % (p1, len(data)//2, data)
		return self._tp.send_apdu_checksw(pdu)

	def set_data(self, ef, tag:int, value:str, verify:bool=False, conserve:bool=False):
		"""Execute SET DATA.

		Args
			ef : string or list of strings indicating name or path of transparent EF
			tag : BER-TLV Tag of value to be stored
			value : BER-TLV value to be stored
		"""
		r = self.select_path(ef)
		if len(r[-1]) == 0:
			return (None, None)

		# in case of deleting the data, we only have 'tag' but no 'value'
		if not value:
			return self._set_data('%02x' % tag, first=True)

		# FIXME: proper BER-TLV encode
		tl = '%02x%s' % (tag, b2h(bertlv_encode_len(len(value)//2)))
		tlv = tl + value
		tlv_bin = h2b(tlv)

		first = True
		total_len = len(tlv_bin)
		remaining = tlv_bin
		while len(remaining) > 0:
			fragment = remaining[:255]
			rdata, sw = self._set_data(fragment, first=first)
			first = False
			remaining = remaining[255:]
		return rdata, sw

	def run_gsm(self, rand:str):
		"""Execute RUN GSM ALGORITHM.

		Args:
			rand : 16 byte random data as hex string (RAND)
		"""
		if len(rand) != 32:
			raise ValueError('Invalid rand')
		self.select_path(['3f00', '7f20'])
		return self._tp.send_apdu(self.cla_byte + '88000010' + rand)

	def authenticate(self, rand:str, autn:str, context='3g'):
		"""Execute AUTHENTICATE (USIM/ISIM).

		Args:
			rand : 16 byte random data as hex string (RAND)
			autn : 8 byte Autentication Token (AUTN)
			context : 16 byte random data ('3g' or 'gsm')
		"""
		# 3GPP TS 31.102 Section 7.1.2.1
		AuthCmd3G = Struct('rand'/LV, 'autn'/Optional(LV))
		AuthResp3GSyncFail = Struct(Const(b'\xDC'), 'auts'/LV)
		AuthResp3GSuccess = Struct(Const(b'\xDB'), 'res'/LV, 'ck'/LV, 'ik'/LV, 'kc'/Optional(LV))
		AuthResp3G = Select(AuthResp3GSyncFail, AuthResp3GSuccess)
		# build parameters
		cmd_data = {'rand': rand, 'autn': autn}
		if context == '3g':
			p2 = '81'
		elif context == 'gsm':
			p2 = '80'
		(data, sw) = self._tp.send_apdu_constr_checksw(self.cla_byte, '88', '00', p2, AuthCmd3G, cmd_data, AuthResp3G)
		if 'auts' in data:
			ret = {'synchronisation_failure': data}
		else:
			ret = {'successful_3g_authentication': data}
		return (ret, sw)

	def status(self):
		"""Execute a STATUS command as per TS 102 221 Section 11.1.2."""
		return self._tp.send_apdu_checksw('80F20000ff')

	def deactivate_file(self):
		"""Execute DECATIVATE FILE command as per TS 102 221 Section 11.1.14."""
		return self._tp.send_apdu_constr_checksw(self.cla_byte, '04', '00', '00', None, None, None)

	def activate_file(self, fid):
		"""Execute ACTIVATE FILE command as per TS 102 221 Section 11.1.15.

		Args:
			fid : file identifier as hex string
		"""
		return self._tp.send_apdu_checksw(self.cla_byte + '44000002' + fid)

	def manage_channel(self, mode='open', lchan_nr=0):
		"""Execute MANAGE CHANNEL command as per TS 102 221 Section 11.1.17.

		Args:
			mode : logical channel operation code ('open' or 'close')
			lchan_nr : logical channel number (1-19, 0=assigned by UICC)
		"""
		if mode == 'close':
			p1 = 0x80
		else:
			p1 = 0x00
		pdu = self.cla_byte + '70%02x%02x00' % (p1, lchan_nr)
		return self._tp.send_apdu_checksw(pdu)

	def reset_card(self):
		"""Physically reset the card"""
		return self._tp.reset_card()

	def _chv_process_sw(self, op_name, chv_no, pin_code, sw):
		if sw_match(sw, '63cx'):
			raise RuntimeError('Failed to %s chv_no 0x%02X with code 0x%s, %i tries left.' %
							   (op_name, chv_no, b2h(pin_code).upper(), int(sw[3])))
		elif (sw != '9000'):
			raise SwMatchError(sw, '9000')

	def verify_chv(self, chv_no:int, code:str):
		"""Verify a given CHV (Card Holder Verification == PIN)

		Args:
			chv_no : chv number (1=CHV1, 2=CHV2, ...)
			code : chv code as hex string
		"""
		fc = rpad(b2h(code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)
		self._chv_process_sw('verify', chv_no, code, sw)
		return (data, sw)

	def unblock_chv(self, chv_no:int, puk_code:str, pin_code:str):
		"""Unblock a given CHV (Card Holder Verification == PIN)

		Args:
			chv_no : chv number (1=CHV1, 2=CHV2, ...)
			puk_code : puk code as hex string
			pin_code : new chv code as hex string
		"""
		fc = rpad(b2h(puk_code), 16) + rpad(b2h(pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2C00' + ('%02X' % chv_no) + '10' + fc)
		self._chv_process_sw('unblock', chv_no, pin_code, sw)
		return (data, sw)

	def change_chv(self, chv_no:int, pin_code:str, new_pin_code:str):
		"""Change a given CHV (Card Holder Verification == PIN)

		Args:
			chv_no : chv number (1=CHV1, 2=CHV2, ...)
			pin_code : current chv code as hex string
			new_pin_code : new chv code as hex string
		"""
		fc = rpad(b2h(pin_code), 16) + rpad(b2h(new_pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2400' + ('%02X' % chv_no) + '10' + fc)
		self._chv_process_sw('change', chv_no, pin_code, sw)
		return (data, sw)

	def disable_chv(self, chv_no:int, pin_code:str):
		"""Disable a given CHV (Card Holder Verification == PIN)

		Args:
			chv_no : chv number (1=CHV1, 2=CHV2, ...)
			pin_code : current chv code as hex string
			new_pin_code : new chv code as hex string
		"""
		fc = rpad(b2h(pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2600' + ('%02X' % chv_no) + '08' + fc)
		self._chv_process_sw('disable', chv_no, pin_code, sw)
		return (data, sw)

	def enable_chv(self, chv_no:int, pin_code:str):
		"""Enable a given CHV (Card Holder Verification == PIN)

		Args:
			chv_no : chv number (1=CHV1, 2=CHV2, ...)
			pin_code : chv code as hex string
		"""
		fc = rpad(b2h(pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2800' + ('%02X' % chv_no) + '08' + fc)
		self._chv_process_sw('enable', chv_no, pin_code, sw)
		return (data, sw)

	def envelope(self, payload:str):
		"""Send one ENVELOPE command to the SIM

		Args:
			payload : payload as hex string
		"""
		return self._tp.send_apdu_checksw('80c20000%02x%s' % (len(payload)//2, payload))

	def terminal_profile(self, payload:str):
		"""Send TERMINAL PROFILE to card

		Args:
			payload : payload as hex string
		"""
		data_length = len(payload) // 2
		data, sw = self._tp.send_apdu(('80100000%02x' % data_length) + payload)
		return (data, sw)

	# ETSI TS 102 221 11.1.22
	def suspend_uicc(self, min_len_secs:int=60, max_len_secs:int=43200):
		"""Send SUSPEND UICC to the card.

		Args:
			 min_len_secs : mimumum suspend time seconds
			 max_len_secs : maximum suspend time seconds
		"""
		def encode_duration(secs:int) -> Hexstr:
			if secs >= 10*24*60*60:
				return '04%02x' % (secs // (10*24*60*60))
			elif secs >= 24*60*60:
				return '03%02x' % (secs // (24*60*60))
			elif secs >= 60*60:
				return '02%02x' % (secs // (60*60))
			elif secs >= 60:
				return '01%02x' % (secs // 60)
			else:
				return '00%02x' % secs
		def decode_duration(enc:Hexstr) -> int:
			time_unit = enc[:2]
			length = h2i(enc[2:4])
			if time_unit == '04':
				return length * 10*24*60*60
			elif time_unit == '03':
				return length * 24*60*60
			elif time_unit == '02':
				return length * 60*60
			elif time_unit == '01':
				return length * 60
			elif time_unit == '00':
				return length
			else:
				raise ValueError('Time unit must be 0x00..0x04')
		min_dur_enc = encode_duration(min_len_secs)
		max_dur_enc = encode_duration(max_len_secs)
		data, sw = self._tp.send_apdu_checksw('8076000004' + min_dur_enc + max_dur_enc)
		negotiated_duration_secs = decode_duration(data[:4])
		resume_token = data[4:]
		return (negotiated_duration_secs, resume_token, sw)
