import unittest
from unittest.mock import PropertyMock, patch

from streamlink import Streamlink
from streamlink.plugins.filmon import FilmOnHLS
from streamlink.stream.hls import HLSStream
from streamlink.stream.http import HTTPStream
from streamlink.stream.stream import Stream
from streamlink_cli.utils import stream_to_url


class TestStreamToURL(unittest.TestCase):
    def setUp(self):
        self.session = Streamlink()

    def test_base_stream(self):
        stream = Stream(self.session)
        self.assertEqual(None, stream_to_url(stream))
        self.assertRaises(TypeError, stream.to_url)

    def test_http_stream(self):
        expected = "http://test.se/stream"
        stream = HTTPStream(self.session, expected, invalid_arg="invalid")
        self.assertEqual(expected, stream_to_url(stream))
        self.assertEqual(expected, stream.to_url())

    def test_hls_stream(self):
        expected = "http://test.se/stream.m3u8"
        stream = HLSStream(self.session, expected)
        self.assertEqual(expected, stream_to_url(stream))
        self.assertEqual(expected, stream.to_url())

    @patch("time.time")
    @patch("streamlink.plugins.filmon.FilmOnHLS.url", new_callable=PropertyMock)
    def test_filmon_stream(self, url, time):
        stream = FilmOnHLS(self.session, channel="test")
        url.return_value = "http://filmon.test.se/test.m3u8"
        stream.watch_timeout = 10
        time.return_value = 1
        expected = "http://filmon.test.se/test.m3u8"

        self.assertEqual(expected, stream_to_url(stream))
        self.assertEqual(expected, stream.to_url())

    @patch("time.time")
    @patch("streamlink.plugins.filmon.FilmOnHLS.url", new_callable=PropertyMock)
    def test_filmon_expired_stream(self, url, time):
        stream = FilmOnHLS(self.session, channel="test")
        url.return_value = "http://filmon.test.se/test.m3u8"
        stream.watch_timeout = 0
        time.return_value = 1

        self.assertEqual(None, stream_to_url(stream))
        self.assertRaises(TypeError, stream.to_url)
