import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from "typeorm";
import WebTorrent from "webtorrent-hybrid";

@Entity()
export default class Torrent extends BaseEntity
{
    static fromWebTorrent(torrent: WebTorrent.Torrent) {
        let entity = new Torrent();
        entity.infoHash = torrent.infoHash;
        entity.torrentFile = torrent.torrentFile;
        entity.setSelectedFiles(torrent.files);
        entity.downloadPath = torrent.path;
        return entity;
    }

    @PrimaryGeneratedColumn()
    id!: number;

    @Column()
    infoHash!: string;

    @Column("mediumblob")
    torrentFile!: Buffer;

    @Column({nullable: true})
    selectOnly?: string;

    @Column()
    downloadPath!: string;

    /**
     * Get the list of selected files
     */
    selectedFiles() {
        let result: number[] = [];
        for (let range of (this.selectOnly ?? "").split(',')) {
            // @TODO Check this map function... it's weird
            let [index, end] = range.split('-').map(num => parseInt(num));
            do {
                result.push(index);
            } while(index++ < end);
        }
        return result;
    }

    /**
     * Update the selected files from the torrent
     */
    setSelectedFiles(files: WebTorrent.TorrentFile[]) {
        let ranges: string[] = [];
        let offset: number | null = null;
        let range: number = 0;
        files.forEach((file, i) => {
            if (file.isSelected) {
                if (offset === null) {
                    offset = i;
                    range = 0;
                } else {
                    range++;
                }
            } else {
                if (offset !== null) {
                    ranges.push(offset + (range > 0 ? `-${offset + range}` : ""));
                    offset = null;
                }
            }
        });
        if (offset !== null) {
            ranges.push(offset + (range > 0 ? `-${offset + range}` : ""));
        }
        this.selectOnly = ranges.join(',');
    }
}
