# -*- coding: utf-8 -*-
# TorrServer API wrapper — adapted from Jacktook's jacktorr.py
# Manages TorrServer connection for P2P torrent streaming
import requests
from requests.auth import HTTPBasicAuth
from json import dumps

class TorrServerError(Exception):
    pass

class TorrServerAPI:
    def __init__(self, host='127.0.0.1', port=8090, username='', password='', ssl_enabled=False):
        self._base_url = "{}://{}:{}".format("https" if ssl_enabled else "http", host, port)
        self._username = username
        self._password = password
        self._auth = HTTPBasicAuth(self._username, self._password) if username else None
        self._session = requests.Session()

    def _get(self, path):
        url = self._base_url + path
        if self._auth:
            return self._session.get(url, auth=self._auth, timeout=30)
        return self._session.get(url, timeout=30)

    def _post(self, path, **kwargs):
        url = self._base_url + path
        if self._auth:
            return self._session.post(url, auth=self._auth, timeout=30, **kwargs)
        return self._session.post(url, timeout=30, **kwargs)

    def _normalize(self, data):
        if isinstance(data, list):
            if not data:
                raise TorrServerError("TorrServer returned empty list")
            return data[0]
        return data

    def _extract_hash(self, response):
        result = self._normalize(response.json())
        return result["hash"]

    @property
    def alive(self):
        try:
            return self._get("/echo").content == b"uptime"
        except:
            return False

    @property
    def version(self):
        try:
            return self._get("/echo").content.decode()
        except:
            return "unknown"

    def add_magnet(self, magnet, title="", poster="", save=True):
        return self._extract_hash(
            self._post("/torrents",
                data=dumps({"action": "add", "link": magnet, "title": title,
                           "poster": poster, "save_to_db": save}),
                headers={"Content-Type": "application/json"}
            )
        )

    def torrents(self):
        return self._post("/torrents",
            data=dumps({"action": "list"}),
            headers={"Content-Type": "application/json"}
        ).json()

    def get_torrent_info(self, hash):
        return self._post("/torrents",
            data=dumps({"action": "get", "hash": hash}),
            headers={"Content-Type": "application/json"}
        ).json()

    def remove_torrent(self, hash):
        return self._post("/torrents",
            data=dumps({"action": "remove", "hash": hash}),
            headers={"Content-Type": "application/json"}
        ).json()

    def get_stream_url(self, hash, file_id=0):
        return "%s/stream?hash=%s&index=%d&link=" % (self._base_url, hash, file_id)

    def play_torrent(self, hash, file_id=0):
        return "%s/play?hash=%s&file_id=%d" % (self._base_url, hash, file_id)

    def get_files(self, hash):
        info = self.get_torrent_info(hash)
        if isinstance(info, list) and info:
            info = info[0]
        return info.get("file_stats", []) if isinstance(info, dict) else []
