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

# Copyright (C) 2018 Vadim Yanitskiy <axilirator@gmail.com>
#
# 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/>.
#

import select
import struct
import socket
import os

from pySim.transport import LinkBase
from pySim.exceptions import *
from pySim.utils import h2b, b2h

class L1CTLMessage(object):

	# Every (encoded) L1CTL message has the following structure:
	#  - msg_length (2 bytes, net order)
	#  - l1ctl_hdr (packed structure)
	#    - msg_type
	#    - flags
	#    - padding (2 spare bytes)
	#  - ... payload ...

	def __init__(self, msg_type, flags = 0x00):
		# Init L1CTL message header
		self.data = struct.pack("BBxx", msg_type, flags)

	def gen_msg(self):
		return struct.pack("!H", len(self.data)) + self.data

class L1CTLMessageReset(L1CTLMessage):

	# L1CTL message types
	L1CTL_RESET_REQ		= 0x0d
	L1CTL_RESET_IND		= 0x07
	L1CTL_RESET_CONF	= 0x0e

	# Reset types
	L1CTL_RES_T_BOOT	= 0x00
	L1CTL_RES_T_FULL	= 0x01
	L1CTL_RES_T_SCHED	= 0x02

	def __init__(self, type = L1CTL_RES_T_FULL):
		super(L1CTLMessageReset, self).__init__(self.L1CTL_RESET_REQ)
		self.data += struct.pack("Bxxx", type)

class L1CTLMessageSIM(L1CTLMessage):

	# SIM related message types
	L1CTL_SIM_REQ		= 0x16
	L1CTL_SIM_CONF		= 0x17

	def __init__(self, pdu):
		super(L1CTLMessageSIM, self).__init__(self.L1CTL_SIM_REQ)
		self.data += pdu

class CalypsoSimLink(LinkBase):
	"""Transport Link for Calypso based phones."""

	def __init__(self, sock_path:str = "/tmp/osmocom_l2"):
		# Make sure that a given socket path exists
		if not os.path.exists(sock_path):
			raise ReaderError("There is no such ('%s') UNIX socket" % sock_path)

		print("Connecting to osmocon at '%s'..." % sock_path)

		# Establish a client connection
		self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
		self.sock.connect(sock_path)

	def __del__(self):
		self.sock.close()

	def wait_for_rsp(self, exp_len = 128):
		# Wait for incoming data (timeout is 3 seconds)
		s, _, _ = select.select([self.sock], [], [], 3.0)
		if not s:
			raise ReaderError("Timeout waiting for card response")

		# Receive expected amount of bytes from osmocon
		rsp = self.sock.recv(exp_len)
		return rsp

	def reset_card(self):
		# Request FULL reset
		req_msg = L1CTLMessageReset()
		self.sock.send(req_msg.gen_msg())

		# Wait for confirmation
		rsp = self.wait_for_rsp()
		rsp_msg = struct.unpack_from("!HB", rsp)
		if rsp_msg[1] != L1CTLMessageReset.L1CTL_RESET_CONF:
			raise ReaderError("Failed to reset Calypso PHY")

	def connect(self):
		self.reset_card()

	def disconnect(self):
		pass # Nothing to do really ...

	def wait_for_card(self, timeout = None, newcardonly = False):
		pass # Nothing to do really ...

	def send_apdu_raw(self, pdu):

		# Request FULL reset
		req_msg = L1CTLMessageSIM(h2b(pdu))
		self.sock.send(req_msg.gen_msg())

		# Read message length first
		rsp = self.wait_for_rsp(struct.calcsize("!H"))
		msg_len = struct.unpack_from("!H", rsp)[0]
		if msg_len < struct.calcsize("BBxx"):
			raise ReaderError("Missing L1CTL header for L1CTL_SIM_CONF")

		# Read the whole message then
		rsp = self.sock.recv(msg_len)

		# Verify L1CTL header
		hdr = struct.unpack_from("BBxx", rsp)
		if hdr[0] != L1CTLMessageSIM.L1CTL_SIM_CONF:
			raise ReaderError("Unexpected L1CTL message received")

		# Verify the payload length
		offset = struct.calcsize("BBxx")
		if len(rsp) <= offset:
			raise ProtocolError("Empty response from SIM?!?")

		# Omit L1CTL header
		rsp = rsp[offset:]

		# Unpack data and SW
		data = rsp[:-2]
		sw = rsp[-2:]

		return b2h(data), b2h(sw)
