#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from __future__ import absolute_import

import errno
import socket
import select
import time

from typing import TYPE_CHECKING, Tuple, List

if TYPE_CHECKING:
    from proton._selectable import Selectable

PN_INVALID_SOCKET = -1


class IO(object):

    @staticmethod
    def _setupsocket(s: socket) -> None:
        s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
        s.setblocking(False)

    @staticmethod
    def close(s: socket) -> None:
        s.close()

    @staticmethod
    def listen(host, port):
        s = socket.socket()
        IO._setupsocket(s)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        s.bind((host, port))
        s.listen(10)
        return s

    @staticmethod
    def accept(s: socket):
        n = s.accept()
        IO._setupsocket(n[0])
        return n

    @staticmethod
    def connect(addr):
        s = socket.socket(addr[0], addr[1], addr[2])
        IO._setupsocket(s)
        try:
            s.connect(addr[4])
        except socket.error as e:
            if e.errno not in (errno.EINPROGRESS, errno.EWOULDBLOCK, errno.EAGAIN):
                raise
        return s

    @staticmethod
    def select(*args, **kwargs):
        return select.select(*args, **kwargs)

    @staticmethod
    def sleep(t: float) -> None:
        time.sleep(t)
        return

    class Selector(object):

        def __init__(self) -> None:
            self._selectables = set()
            self._reading = set()
            self._writing = set()
            self._deadline = None

        def add(self, selectable: 'Selectable') -> None:
            self._selectables.add(selectable)
            if selectable.reading:
                self._reading.add(selectable)
            if selectable.writing:
                self._writing.add(selectable)
            if selectable.deadline:
                if self._deadline is None:
                    self._deadline = selectable.deadline
                else:
                    self._deadline = min(selectable.deadline, self._deadline)

        def remove(self, selectable: 'Selectable') -> None:
            self._selectables.discard(selectable)
            self._reading.discard(selectable)
            self._writing.discard(selectable)
            self.update_deadline()

        @property
        def selectables(self) -> int:
            return len(self._selectables)

        def update_deadline(self) -> None:
            for sel in self._selectables:
                if sel.deadline:
                    if self._deadline is None:
                        self._deadline = sel.deadline
                    else:
                        self._deadline = min(sel.deadline, self._deadline)

        def update(self, selectable: 'Selectable') -> None:
            self._reading.discard(selectable)
            self._writing.discard(selectable)
            if selectable.reading:
                self._reading.add(selectable)
            if selectable.writing:
                self._writing.add(selectable)
            self.update_deadline()

        def select(self, timeout: float) -> Tuple[List, List, List]:

            def select_inner(timeout):
                # This inner select adds the writing fds to the exception fd set
                # because Windows returns connected fds in the exception set not the
                # writable set
                r = self._reading
                w = self._writing

                now = time.time()

                # No timeout or deadline
                if timeout is None and self._deadline is None:
                    return IO.select(r, w, w)

                if timeout is None:
                    t = max(0, self._deadline - now)
                    return IO.select(r, w, w, t)

                if self._deadline is None:
                    return IO.select(r, w, w, timeout)

                t = max(0, min(timeout, self._deadline - now))
                if len(r) == 0 and len(w) == 0:
                    if t > 0:
                        IO.sleep(t)
                    return ([], [], [])

                return IO.select(r, w, w, t)

            # Need to allow for signals interrupting us on Python 2
            # In this case the signal handler could have messed up our internal state
            # so don't retry just return with no handles.
            try:
                r, w, ex = select_inner(timeout)
            except select.error as e:
                if e.errno != errno.EINTR:
                    raise
                r, w, ex = ([], [], [])

            # For windows non blocking connect we get exception not writable so add exceptions to writable
            w += ex

            # Calculate timed out selectables
            now = time.time()
            t = [s for s in self._selectables if s.deadline and now > s.deadline]
            self._deadline = None
            self.update_deadline()
            return r, w, t
