import time

from ..extensions import BinaryReader, BinaryWriter


class MtProtoPlainSender:
    """MTProto Mobile Protocol plain sender
       (https://core.telegram.org/mtproto/description#unencrypted-messages)
    """

    def __init__(self, connection):
        self._sequence = 0
        self._time_offset = 0
        self._last_msg_id = 0
        self._connection = connection

    def connect(self):
        self._connection.connect()

    def disconnect(self):
        self._connection.close()

    def send(self, data):
        """Sends a plain packet (auth_key_id = 0) containing the
           given message body (data)
        """
        with BinaryWriter(known_length=len(data) + 20) as writer:
            writer.write_long(0)
            writer.write_long(self._get_new_msg_id())
            writer.write_int(len(data))
            writer.write(data)

            packet = writer.get_bytes()
            self._connection.send(packet)

    def receive(self):
        """Receives a plain packet, returning the body of the response"""
        body = self._connection.recv()
        with BinaryReader(body) as reader:
            reader.read_long()  # auth_key_id
            reader.read_long()  # msg_id
            message_length = reader.read_int()

            response = reader.read(message_length)
            return response

    def _get_new_msg_id(self):
        """Generates a new message ID based on the current time since epoch"""
        # See core.telegram.org/mtproto/description#message-identifier-msg-id
        now = time.time()
        nanoseconds = int((now - int(now)) * 1e+9)
        # "message identifiers are divisible by 4"
        new_msg_id = (int(now) << 32) | (nanoseconds << 2)
        if self._last_msg_id >= new_msg_id:
            new_msg_id = self._last_msg_id + 4

        self._last_msg_id = new_msg_id
        return new_msg_id
