#!/usr/bin/env python

import logging
import os
import re
import socket
import subprocess
import sys
import time

from http_server_driver import HTTPServerDriver


_log = logging.getLogger(__name__)


class SimpleHTTPServerDriver(HTTPServerDriver):

    """This class depends on unix environment, need to be modified to achieve crossplatform compability
    """

    platforms = ['osx', 'linux']

    def __init__(self):
        self._server_process = None
        self._server_port = 0
        self._ip = '127.0.0.1'
        self._ensure_http_server_dependencies()

    def serve(self, web_root):
        _log.info('Launching an http server')
        http_server_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "http_server/twisted_http_server.py")
        self._server_process = subprocess.Popen(["python", http_server_path, web_root], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        max_attempt = 5
        interval = 0.5
        _log.info('Start to fetching the port number of the http server')
        try:
            import psutil
            for attempt in xrange(max_attempt):
                connections = psutil.Process(self._server_process.pid).connections()
                if connections and connections[0].laddr and connections[0].laddr[1] and connections[0].status == 'LISTEN':
                    self._server_port = connections[0].laddr[1]
                    _log.info('HTTP Server is serving at port: %d', self._server_port)
                    break
                _log.info('Server port is not found this time, retry after %f seconds' % interval)
                time.sleep(interval)
                interval *= 2
            else:
                raise Exception("Server is not listening on port, max tries exceeded. HTTP server may be installing dependent modules.")
        except ImportError:
            for attempt in xrange(max_attempt):
                try:
                    output = subprocess.check_output(['/usr/sbin/lsof', '-a', '-iTCP', '-sTCP:LISTEN', '-p', str(self._server_process.pid)])
                    self._server_port = int(re.search('TCP \*:(\d+) \(LISTEN\)', output).group(1))
                    if self._server_port:
                        _log.info('HTTP Server is serving at port: %d', self._server_port)
                        break
                except Exception as error:
                    _log.info('Error: %s' % error)
                _log.info('Server port is not found this time, retry after %f seconds' % interval)
                time.sleep(interval)
                interval *= 2
            else:
                raise Exception("Cannot listen to server, max tries exceeded")

        # Wait for server to be up completely before exiting
        for attempt in xrange(max_attempt):
            try:
                subprocess.check_call(["curl", "--silent", "--head", "--fail", "--output", "/dev/null", self.base_url()])
                return
            except Exception as error:
                _log.info('Server not running yet: %s' % error)
                time.sleep(interval)
        raise Exception('Server not running, max tries exceeded: %s' % error)

    def base_url(self):
        return "http://%s:%d" % (self._ip, self._server_port)

    def fetch_result(self):
        (stdout, stderr) = self._server_process.communicate()
        print(stderr)
        return stdout

    def kill_server(self):
        try:
            if self._server_process.poll() is None:
                self._server_process.terminate()
        except OSError as error:
            _log.info('Error terminating server process: %s' % (error))

    def get_return_code(self):
        return self._server_process.returncode

    def set_device_id(self, device_id):
        pass

    def _ensure_http_server_dependencies(self):
        _log.info('Ensure dependencies of http server is satisfied')
        from pkg_resources import require, VersionConflict, DistributionNotFound
        try:
            require("Twisted>=15.5.0")
            import twisted
        except (ImportError, VersionConflict, DistributionNotFound):
            _log.info("Will install twisted in webkitpy, and twisted will be used by webkitpy only")
            sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../../..')))
            from webkitpy.thirdparty.autoinstalled.twisted_15_5_0 import twisted
