from __future__ import division

import errno
import logging
import threading

import av.error
import av.logging

from .common import TestCase


def do_log(message):
    av.logging.log(av.logging.INFO, 'test', message)


class TestLogging(TestCase):

    def test_adapt_level(self):
        self.assertEqual(
            av.logging.adapt_level(av.logging.ERROR),
            logging.ERROR
        )
        self.assertEqual(
            av.logging.adapt_level(av.logging.WARNING),
            logging.WARNING
        )
        self.assertEqual(
            av.logging.adapt_level((av.logging.WARNING + av.logging.ERROR) // 2),
            logging.WARNING
        )

    def test_threaded_captures(self):

        with av.logging.Capture(local=True) as logs:
            do_log('main')
            thread = threading.Thread(target=do_log, args=('thread', ))
            thread.start()
            thread.join()

        self.assertIn((av.logging.INFO, 'test', 'main'), logs)

    def test_global_captures(self):

        with av.logging.Capture(local=False) as logs:
            do_log('main')
            thread = threading.Thread(target=do_log, args=('thread', ))
            thread.start()
            thread.join()

        self.assertIn((av.logging.INFO, 'test', 'main'), logs)
        self.assertIn((av.logging.INFO, 'test', 'thread'), logs)

    def test_repeats(self):

        with av.logging.Capture() as logs:
            do_log('foo')
            do_log('foo')
            do_log('bar')
            do_log('bar')
            do_log('bar')
            do_log('baz')

        logs = [log for log in logs if log[1] == 'test']

        self.assertEqual(logs, [
            (av.logging.INFO, 'test', 'foo'),
            (av.logging.INFO, 'test', 'foo'),
            (av.logging.INFO, 'test', 'bar'),
            (av.logging.INFO, 'test', 'bar (repeated 2 more times)'),
            (av.logging.INFO, 'test', 'baz'),

        ])

    def test_error(self):

        log = (av.logging.ERROR, 'test', 'This is a test.')
        av.logging.log(*log)
        try:
            av.error.err_check(-errno.EPERM)
        except OSError as e:
            self.assertEqual(e.log, log)
        else:
            self.fail()
