import { IpcClientService } from "@autoplex/ipc";
import { Microservice } from "@autoplex/microservice";
import { SOCKET_PATH } from "./constants";
import { ISerializedTorrent, ITorrent } from "./schema";

export class IpcClient<M extends Microservice = Microservice> extends IpcClientService<M>
{
    /**
     * The name of the service
     */
    public readonly NAME = "Torrent";

    /**
     * The path to the socket file
     */
    protected readonly SOCKET_PATH = SOCKET_PATH;

	/**
     * Add a torrent to the client
     * @param torrent Magnet URI or file buffer
     */
    public async add(torrent: string | Buffer, downloadPath?: string) {
        let response = await this.request("add", { torrent, downloadPath });
        if (response.error) {
            throw new Error("Failed to add torrent");
        }
        return <string>response.data;
    }

    /**
     * Remove a torrent from the client
     * @param torrent Torrent info hash
     */
    public async remove(torrentId: string, withData: boolean = false) {
        let response = await this.request("remove", { torrentId, withData });
        if (response.error) {
            throw new Error("Failed to remove torrent");
        }
    }

    /**
     * Get a list of all torrents in the client
     */
    public async list() {
        let response = await this.request("list");
        if (response.error) {
            console.error(response.error);
            throw new Error("Failed to obtain torrent list");
        }
        return <ITorrent[]>response.data;
    }

    /**
     * Check if the torrent client has the given torrent
     */
    public async has(torrentId: string) {
        let response = await this.request("has", torrentId);
        if (response.error) {
            console.error(response.error);
            throw new Error("Failed to check if a torrent exists");
        }
        return <boolean>response.data;
    }

    /**
     * Get full details of each of the provided torrents
     */
    public async details(torrentIds: string[] = []) {
        let response = await this.request("details", torrentIds);
        if (response.error) {
            console.error(response.error);
            throw new Error("Failed to retrieve torrent details");
        }
        return <ISerializedTorrent[]>response.data;
    }
}
