# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import collections
import contextlib
import logging
import os
import signal
import socket
import sys

import mock
import pytest
import subprocess32

from lucifer import leasing

logger = logging.getLogger(__name__)

# 9999-01-01T00:00:00+00:00
_THE_END = 253370764800


def test_obtain_lease(tmpdir):
    """Test obtain_lease.

    Provides basic test coverage metrics.  The slower subprocess tests
    provide better functional coverage.
    """
    path = _make_lease(tmpdir, 124)
    with leasing.obtain_lease(path):
        pass
    assert not os.path.exists(path)


@pytest.mark.slow
def test_obtain_lease_succesfully_removes_file(tmpdir):
    """Test obtain_lease cleans up lease file if successful."""
    path = _make_lease(tmpdir, 124)
    with _obtain_lease(path) as lease_proc:
        lease_proc.finish()
    assert not os.path.exists(path)


@pytest.mark.slow
def test_obtain_lease_with_error_removes_files(tmpdir):
    """Test obtain_lease removes file if it errors."""
    path = _make_lease(tmpdir, 124)
    with _obtain_lease(path) as lease_proc:
        lease_proc.proc.send_signal(signal.SIGINT)
        lease_proc.proc.wait()
    assert not os.path.exists(path)


@pytest.mark.slow
def test_Lease_expired(tmpdir, end_time):
    """Test Lease.Expired()."""
    _make_lease(tmpdir, 123)
    path = _make_lease(tmpdir, 124)
    with _obtain_lease(path):
        leases = _leases_dict(str(tmpdir))
        assert leases[123].expired()
        assert not leases[124].expired()


def test_unlocked_fresh_leases_are_not_expired(tmpdir):
    """Test get_expired_leases()."""
    path = _make_lease(tmpdir, 123)
    os.utime(path, (_THE_END, _THE_END))
    leases = _leases_dict(str(tmpdir))
    assert not leases[123].expired()


def test_leases_iter_with_sock_files(tmpdir):
    """Test leases_iter() ignores sock files."""
    _make_lease(tmpdir, 123)
    tmpdir.join('124.sock').write('')
    leases = _leases_dict(str(tmpdir))
    assert 124 not in leases


def test_Lease_cleanup(tmpdir):
    """Test Lease.cleanup()."""
    lease_path = _make_lease(tmpdir, 123)
    tmpdir.join('123.sock').write('')
    sock_path = str(tmpdir.join('123.sock'))
    for lease in leasing.leases_iter(str(tmpdir)):
        logger.debug('Cleaning up %r', lease)
        lease.cleanup()
    assert not os.path.exists(lease_path)
    assert not os.path.exists(sock_path)


def test_Lease_cleanup_does_not_raise_on_error(tmpdir):
    """Test Lease.cleanup()."""
    lease_path = _make_lease(tmpdir, 123)
    tmpdir.join('123.sock').write('')
    sock_path = str(tmpdir.join('123.sock'))
    for lease in leasing.leases_iter(str(tmpdir)):
        os.unlink(lease_path)
        os.unlink(sock_path)
        lease.cleanup()


@pytest.mark.slow
def test_Lease_abort(tmpdir):
    """Test Lease.abort()."""
    _make_lease(tmpdir, 123)
    with _abort_socket(tmpdir, 123) as proc:
        expired = list(leasing.leases_iter(str(tmpdir)))
        assert len(expired) > 0
        for lease in expired:
            lease.abort()
        proc.wait()
        assert proc.returncode == 0


@pytest.mark.slow
def test_Lease_abort_with_closed_socket(tmpdir):
    """Test Lease.abort() with closed socket."""
    _make_lease(tmpdir, 123)
    with _abort_socket(tmpdir, 123) as proc:
        proc.terminate()
        proc.wait()
        expired = list(leasing.leases_iter(str(tmpdir)))
        assert len(expired) > 0
        for lease in expired:
            with pytest.raises(socket.error):
                lease.abort()


@pytest.mark.slow
def test_Lease_abort_with_blocked_socket(tmpdir):
    """Test Lease.abort() with blocked socket.

    If the behavior this test is looking for is missing (a raised error
    for nonblock write timeout), this test will hang indefinitely on a
    blocking socket read.
    """
    _make_lease(tmpdir, 123)
    with _abort_socket_norecv(tmpdir, 123):
        expired = list(leasing.leases_iter(str(tmpdir)))
        assert len(expired) == 1
        lease = expired[0]
        with pytest.raises(socket.error):
            while True:
                lease.abort()


@pytest.fixture
def end_time():
    """Mock out time.time to return a time in the future."""
    with mock.patch('time.time', return_value=_THE_END) as t:
        yield t


_LeaseProc = collections.namedtuple('_LeaseProc', 'finish proc')


@contextlib.contextmanager
def _obtain_lease(path):
    """Lock a lease file.

    Yields a _LeaseProc.  finish is a function that can be called to
    finish the process normally.  proc is a Popen instance.

    This uses a slow subprocess; any test that uses this should be
    marked slow.
    """
    with subprocess32.Popen(
            [sys.executable, '-um',
             'lucifer.cmd.test.obtain_lease', path],
            stdin=subprocess32.PIPE,
            stdout=subprocess32.PIPE) as proc:
        # Wait for lock grab.
        proc.stdout.readline()

        def finish():
            """Finish lease process normally."""
            proc.stdin.write('\n')
            # Wait for lease release.
            proc.stdout.readline()
        try:
            yield _LeaseProc(finish, proc)
        finally:
            proc.terminate()


@contextlib.contextmanager
def _abort_socket(tmpdir, job_id):
    """Open a testing abort socket and listener for a job.

    As a context manager, returns the Popen instance for the listener
    process when entering.

    This uses a slow subprocess; any test that uses this should be
    marked slow.
    """
    path = os.path.join(str(tmpdir), '%d.sock' % job_id)
    logger.debug('Making abort socket at %s', path)
    with subprocess32.Popen(
            [sys.executable, '-um',
             'lucifer.cmd.test.abort_socket', path],
            stdout=subprocess32.PIPE) as proc:
        # Wait for socket bind.
        proc.stdout.readline()
        try:
            yield proc
        finally:
            proc.terminate()


@contextlib.contextmanager
def _abort_socket_norecv(tmpdir, job_id):
    """Open a testing abort socket and bad listener for a job.

    The listening process doesn't actually call recv().

    As a context manager, returns the Popen instance for the listener
    process when entering.

    This uses a slow subprocess; any test that uses this should be
    marked slow.
    """
    path = os.path.join(str(tmpdir), '%d.sock' % job_id)
    logger.debug('Making abort socket at %s', path)
    with subprocess32.Popen(
            [sys.executable, '-um',
             'lucifer.cmd.test.abort_socket_norecv', path],
            stdout=subprocess32.PIPE) as proc:
        # Wait for socket bind.
        proc.stdout.readline()
        try:
            yield proc
        finally:
            proc.terminate()


def _leases_dict(jobdir):
    """Convenience method for tests."""
    return {lease.id: lease for lease
            in leasing.leases_iter(jobdir)}


def _make_lease(tmpdir, job_id):
    return _make_lease_file(str(tmpdir), job_id)


def _make_lease_file(jobdir, job_id):
    """Make lease file corresponding to a job.

    @param jobdir: job lease file directory
    @param job_id: Job ID
    """
    path = os.path.join(jobdir, str(job_id))
    with open(path, 'w'):
        pass
    return path


class _TestError(Exception):
    """Error for tests."""
