import errno
import traceback

import av

from .common import TestCase, is_windows


class TestErrorBasics(TestCase):

    def test_stringify(self):

        for cls in (av.ValueError, av.FileNotFoundError, av.DecoderNotFoundError):
            e = cls(1, 'foo')
            self.assertEqual(str(e), '[Errno 1] foo')
            self.assertEqual(repr(e), "{}(1, 'foo')".format(cls.__name__))
            self.assertEqual(
                traceback.format_exception_only(cls, e)[-1],
                '{}{}: [Errno 1] foo\n'.format(
                    'av.error.',
                    cls.__name__,
                ),
            )

        for cls in (av.ValueError, av.FileNotFoundError, av.DecoderNotFoundError):
            e = cls(1, 'foo', 'bar.txt')
            self.assertEqual(str(e), "[Errno 1] foo: 'bar.txt'")
            self.assertEqual(repr(e), "{}(1, 'foo', 'bar.txt')".format(cls.__name__))
            self.assertEqual(
                traceback.format_exception_only(cls, e)[-1],
                "{}{}: [Errno 1] foo: 'bar.txt'\n".format(
                    'av.error.',
                    cls.__name__,
                ),
            )

    def test_bases(self):

        self.assertTrue(issubclass(av.ValueError, ValueError))
        self.assertTrue(issubclass(av.ValueError, av.FFmpegError))

        self.assertTrue(issubclass(av.FileNotFoundError, FileNotFoundError))
        self.assertTrue(issubclass(av.FileNotFoundError, OSError))
        self.assertTrue(issubclass(av.FileNotFoundError, av.FFmpegError))

    def test_filenotfound(self):
        """Catch using builtin class on Python 3.3"""
        try:
            av.open('does not exist')
        except FileNotFoundError as e:
            self.assertEqual(e.errno, errno.ENOENT)
            if is_windows:
                self.assertTrue(e.strerror in ['Error number -2 occurred',
                                               'No such file or directory'])
            else:
                self.assertEqual(e.strerror, 'No such file or directory')
            self.assertEqual(e.filename, 'does not exist')
        else:
            self.fail('no exception raised')

    def test_buffertoosmall(self):
        """Throw an exception from an enum."""
        try:
            av.error.err_check(-av.error.BUFFER_TOO_SMALL.value)
        except av.BufferTooSmallError as e:
            self.assertEqual(e.errno, av.error.BUFFER_TOO_SMALL.value)
        else:
            self.fail('no exception raised')
