import { IMovieSearchInfo } from "@autoplex-api/torrent-search";
import { jsonRequest } from "../../util";
import Provider, { MediaType } from "../Provider";
import { ErrorCode, ISearchResult, ITokenResponse } from "./schema";

/**
 * The Base URL for the API
 */
const URL_BASE = "https://torrentapi.org/pubapi_v2.php?app_id=autoplex";

/**
 * How frequently to re-authenticate
 */
const AUTH_FREQUENCY = 1000*60*15; // 15 minutes

export default class Rarbg extends Provider
{
	/**
	 * The name of the provider
	 */
	public readonly NAME = "RARBG";

	/**
	 * Indicate the content that the provider provides
	 */
	public readonly PROVIDES = MediaType.Movies | MediaType.TvShows;

	/**
	 * Throttle requests;
	 */
	protected readonly THROTTLE = 1500;

	/**
	 * Since the API is sereverly broken, we need a bunch of retries
	 */
	protected readonly SEARCH_RETRIES = 30;

	/**
	 * Store the time when the API needs to re-authenticate
	 */
	protected nextAuthenticationTime: number = 0;

	/**
	 * The authentication token
	 */
	protected token!: string;

	/**
	 * Indicate if the API is currently authenticated
	 */
	protected async isAuthenticated() {
		return Date.now() < this.nextAuthenticationTime;
	}

	/**
	 * Authenticate the RARBG context
	 */
	protected async authenticate() {
		let now = Date.now();
		let [status, response] = await jsonRequest<ITokenResponse>(
			`${URL_BASE}&get_token=get_token`
		);
		if (status !== 200) {
			return false;
		}
		this.nextAuthenticationTime = now + AUTH_FREQUENCY;
		this.token = response.token;
		return true;
	}

	/**
	 * Search for a movie
	 */
	public async searchMovieImdb(imdbId: string, movie: IMovieSearchInfo) {
		let [_, response] = await jsonRequest<ISearchResult>(
			`${URL_BASE}&token=${this.token}`
			+ `&mode=search&search_imdb=${imdbId}`
			+ "&format=json_extended&limit=100"
		);
		if (response.error_code !== undefined) {
			if (response.error_code === ErrorCode.ImdbNotFound) {
				return []; // Successful search, no results found
			}
			throw new Error("No results found"); // API most likely broke, we need to retry.
		}
		if (response.torrent_results === undefined) {
			throw new Error("Torrents should be defined here");
		}
		return response.torrent_results.map(result => this.createTorrent(
			movie, result.title, result.size, result.seeders, result.download
		));
	}
}
