import logging

import nmap3
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
log = logging.getLogger(__name__)


def discover_ports(url):
    """
    Scan a web server for all available https ports

    :param str url: Url to be scanned
    :return: Usable ports
    :rtype: list
    """
    log.info('Discovering ports with nmap')
    nmap = nmap3.NmapScanTechniques()
    # Scan with nmap for all open ports
    result = nmap.nmap_syn_scan(url, args='-p1-65535')
    open_ports = [port['portid']
                  for port in list(result.items())[0][1]['ports']]
    usable_ports = []
    log.info(f'Scanned ports by nmap : {open_ports}')
    for port in open_ports:
        while True:
            try:
                head = requests.head(f'https://{url}:{port}', timeout=3, verify=False,
                                     headers={'Connection': 'close'})
                if head.status_code < 400:
                    usable_ports.append(int(port))
                    log.debug(f'Port {port} valid')
                    break
            except (requests.exceptions.ReadTimeout, requests.exceptions.Timeout, requests.exceptions.ConnectionError,
                    requests.exceptions.SSLError):
                log.debug(f'Port {port} invalid')
                break
    log.info(f'Found ports: {usable_ports}')
    return usable_ports
