#!/usr/bin/env perl
# Make single M3U8 files instead of a M3U8 playlist
# Needs the MP3::M3U::Parser CPAN module!
# https://github.com/Free-TV/
# https://github.com/iptv-org/
# Usage: mk-iptv -D ~/Videos/IPTV-ALL https://iptv-org.github.io/iptv/index.m3u https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8

use v5.12;

our $VERSION = "1.03";

use Getopt::Std;
our %opts;
getopts( "dD:efpq", \%opts )
    || die("Error in command-line-arguments: $!");

use File::Spec;
use File::HomeDir;
use File::Path;
my $dir = $opts{D} || File::Spec->catfile( File::HomeDir->my_videos, 'IPTV' );
File::Path::remove_tree( $dir, { safe => 1, } ) if ( $opts{d} );
File::Path::make_path($dir);
-d $dir || die $dir, ": directory not found";    # FIXME

use File::Temp;
my ( $fh, $tempfile ) = File::Temp::tempfile();

my @streams;

for ( (@ARGV) ? @ARGV : <DATA> ) {
    chomp;
    use LWP::Simple;
    my $content;
    unless ( defined( $content = get $_) ) {
        warn "Could not get $_";
        next;
    }
    print $fh $content;

    use MP3::M3U::Parser;
    my %options;
    our $parser = MP3::M3U::Parser->new(%options);
    $parser->parse($tempfile);
    my $result = $parser->result;
    my %info   = $parser->info;
    for ( @{$result} ) {
        for ( @{ $_->{data} } ) {
            use URI;
            my $uri = URI->new( @$_[0] ) || next;    # not an URI
            @$_[1]                       || next;    # no ID3 infos
            @$_[2]                       || next;    # no time

            # FIXME
            if ( $opts{p} && !defined( head($uri) ) ) {
                warn "Stream URI seems offline (HTTP head): ", $uri if ( !$opts{q} );
                next;
            }

            if ( grep { "$uri" eq @$_[0] } @streams ) {
                warn "Stream URI seems double: ", $uri if ( !$opts{q} );
                next;
            }

            warn "Add stream: ", $uri if ( !$opts{q} );
            push @streams, $_;
        }
    }
}

my $counter;
for (@streams) {
    my $fn = @$_[1];
    $fn =~ tr/A-Za-z0-9._-//cd;                    # TODO: safty filename
    $fn =~ s/^[.-]+//;
    $fn = sprintf( "%d %s.m3u8", ++$counter, $fn );
    $fn = File::Spec->catfile( $dir, $fn );
    -e $fn && die $fn, ": file already exists" if ( !$opts{f} );    # FIXME

    use IO::File;
    my $fh = IO::File->new( $fn, "w" );
    defined $fh || die $fn, ": can't write to file";
    say $fh "#EXTM3U";
    say $fh "#EXTINF:", @$_[2], ",", @$_[1];
    say $fh @$_[0];
    undef $fh;    # automatically closes the file
}

exit !scalar(@streams);

END {
    unlink $tempfile;
}

__DATA__
https://raw.githubusercontent.com/Free-TV/IPTV/master/playlists/playlist_germany.m3u8
https://iptv-org.github.io/iptv/countries/de.m3u
https://iptv-org.github.io/iptv/languages/deu.m3u
