#!/usr/bin/perl -w

use strict;
use warnings;
#use Switch;

use vars qw($musicdir);
$musicdir = "/var/ftp/pub/music/";

use vars qw($fin $dev);
use vars qw($artist $album $date $tracknum %tracks);

#my $tagfmt="ARTIST=%s\nDATE=%04.4d\nALBUM=%s\nTRACKNUMBER=%02d\nTITLE=%s\nDESCRIPTION=%s\n";
my $tagfmt="ARTIST=%s\nDATE=%04.4d\nALBUM=%s\nTRACKNUMBER=%02d\nTITLE=%s\n";
#my $filefmt_wav="%s/%4.4d-%s/%02.2d-%s.cdda.wav";
#my $filefmt_flac="%s/%4.4d-%s/%02.2d-%s.flac";
my $filefmt_wav="track%02.2d.cdda.wav";	# cdparanoia's format
my $filefmt_flac="%02.2d-%s.flac";

sub printhelp()
{
	print("Usage: $0 CD-MBINFO_FILE [DEVICE]\n");
	print("    CD-MBINDO_FILE  may be - (stdin)\n");
	print("    DEVICE          rip cd from this device\n");
	print("Notes:\n");
	print("    if DEVICE is not specified, output tags for flac for each file\n");
	exit(0);
}


#
my $username = $ENV{'USER'};
if ( ($username eq "") || ($username eq "root") )
{
	print("please run as user because your username will be painted in tags...\nand remember... being root is very bad :)))\n");
	exit(-1);
}
#


my $argc = $#ARGV+1;
if ($argc < 1)
{
	printhelp();
}
else
{
	$fin = $ARGV[0];
	$dev = $ARGV[1] if ( $argc > 1 );
}

if ( -b $fin )
{
	$dev = $fin;
	$fin = "cd-mbinfo.pl \"$fin\" |";
}

open(INP, $fin) or die "can't open input file '$fin': $!\n";
$_ = <INP>;
chomp($_);
if ( /^SCORE=100$/ )
{
	while (<INP>)
	{
		chomp($_);

		$artist = $1 if ( /^ARTIST=(.*)$/ );
		$album  = $1 if ( /^ALBUM=(.*)$/ );
		$date   = $1 if ( /^DATE=([0-9]+).*$/ );	# we just need only year now
		#$date   = $1 if ( /^DATE=(.*)$/ );
		$tracknum = $1 if ( /^TRACKS=([0-9]+)$/ );
		$tracks{"$1"} = "$2" if ( /^TRACK(\d\d)=(.*)$/ );
	}
}
else
{
	print("ERROR: SCORE != 100\nSorry, parsing this case currently not implemented\n");
}
close(INP) or die "broken pipe: $!\n";


#while ( my ($n, $tr) = each (%tracks) )
#{
#	printf($filefmt_wav."\n", $artist, $date, $album, $n, $tr);
#}


# illegal filesystem characters are (and their replacements below):
# /\:;*?"<>|
# ----+_'()-
my $album_safe = $album;
$album_safe =~ s/[\/\\:;\|]/-/g;
$album_safe =~ s/\*/+/g;
$album_safe =~ s/\?/_/g;
$album_safe =~ s/\</\(/g;
$album_safe =~ s/\>/\)/g;
$album_safe =~ s/\"/\'/g;

$musicdir .= "/" if ($musicdir !~ /\/$/);
my $outdir = $musicdir."$artist/$date-$album_safe/";
`mkdir -p "$outdir"` if ( ! -d "$outdir" );

#if ( ! defined($dev) )
#{
#	print("FLAC'ing in: $outdir\n");
#	foreach my $n (sort keys %tracks)
#	{
#		#my $fname = sprintf($filefmt_wav, $artist, $date, $album, $n, $tracks{$n});
#		my $fname = sprintf($filefmt_wav, $n, $tracks{$n});
#		print("$outdir/$fname\n");
#	}
#}
#else
{
my $speed=32;

print("getting device info...\n");
my %drive = ( vendor   => "",
			  model    => "",
			  revision => "",
			  offset   => "" );
my $cdinfo=`cd-info $dev`; 
$_ = $cdinfo;
$drive{vendor}   = $1 if ( /Vendor\s*:\s(\S*)/s );
$drive{model}    = $1 if ( /Model\s*:\s(\S*)/s );
$drive{revision} = $1 if ( /Revision\s*:\s(\S*)/s );
#print("$drive{vendor}\n$drive{model}\n$drive{revision}\n");
if ( ($drive{vendor} eq "") && ($drive{model} eq "") )
{
	print("ERROR: couldn't get drive info :(\n");
	
	exit(-1);
}

# some DIRTY hack here...
if ( "$drive{vendor} $drive{model}" eq "TEAC CD-W552G" )
{ $drive{offset} = 6; }
elsif ( "$drive{vendor} $drive{model}" eq "ASUS DRW-1608P2S" )
{ $drive{offset} = 48; }
else
{
	print("ERROR: i don't know sample correction offset for this device :(\n");
	exit(-1);
}

my $driveinfo = "$drive{vendor} $drive{model} $drive{revision}";
print("$dev: $driveinfo\n");
print("offset: $drive{offset}\n");
print("output: $outdir\n");

my $curdir = `pwd`;
chdir($outdir);

#if (!$force)
my $nwavs=`find -name "*.wav" | wc -l`;
chomp($nwavs);
if ($nwavs > 0)
{
	print("WARNING: specified folder already contains $nwavs wav files!\n");
	print("checking for number of tracks match... ");
	if ($tracknum != $nwavs)
	{
	print("FAILED!\n");
	#exit(-1);
	print("trying to enflac existing wavs...\n");
	}
	else
	{ print("OK\n"); }
}
else
{
	print("TAKE 1...\n");
	`cdparanoia -q -d $dev --sample-offset $drive{offset} -S $speed -w -B`;
	if ($?)
	{
	print("ERROR: cdparanoia returned: $?\n");
	exit($?);
	}

	`md5sum *.wav >md5sums`;

	print("TAKE 2...\n");
	`rm track*.cdda.wav`;		# WARNING!!!!!!!!
	`cdparanoia -q -d $dev --sample-offset $drive{offset} -S $speed -w -B`;
	if ($?)
	{
	print("ERROR: cdparanoia returned: $?\n");
	exit($?);
	}

	print("comparing checksums from 2 takes...\n");
	`md5sum -c md5sums`;
	if ($?)
	{
	print("ERROR: double-take failed :(\n");
	exit(-256);
	}
}

foreach my $n (sort keys %tracks)
{
	#my $fname = sprintf($filefmt_wav, $artist, $date, $album, $n, $tracks{$n});
	#printf($filefmt_wav."\n", $artist, $date, $album, $n, $tracks{$n});
	my $fwav  = sprintf($filefmt_wav, $n);
	# illegal filesystem characters are (and their replacements below):
	# /\:;*?"<>|
	# ----+_'()-
	my $track_name = $tracks{$n};
	$track_name =~ s/[\/\\:;\|]/-/g;
	$track_name =~ s/\*/+/g;
	$track_name =~ s/\?/_/g;
	$track_name =~ s/\</\(/g;
	$track_name =~ s/\>/\)/g;
	$track_name =~ s/\"/\'/g;
	my $fname = sprintf($filefmt_flac, $n, $track_name);
	#print("processing $fwav to $fname: ");
	print("processing $fname ...\n");
	`flac --delete-input-file -s -8 -V -o "$fname" "$fwav"`;
	if ($? == 0)
	{
	#
	#$out=`cat /tmp/tag_album$$.tmp | metaflac --preserve-modtime --export-tags-to="$dirs"\/"$fname".oldtags --remove-all-tags --import-tags-from=- "$cur"`;
	#`rm "$dirs/$fname.oldtag"` if ( -s "$dirs/$fname.oldtag" == 0);

	$tagfmt="ARTIST=%s\nDATE=%04.4d\nALBUM=%s\nTRACKNUMBER=%02d\nTITLE=%s\nDESCRIPTION=%s\n";
	open(MF, "| metaflac --preserve-modtime --export-tags-to=\"$fname.oldtags\" --remove-all-tags --import-tags-from=- \"$fname\"");
	printf MF ($tagfmt, $artist, $date, $album, $n, $tracks{$n}, "ripped by $username ($driveinfo, cdparanoia --sample-offset=$drive{offset}, flac)");
	close(MF);

	`rm "$fname.oldtags"` if ( -s "$fname.oldtags" == 0);

	`echo -n "$fname:" >>metasums`;
	`metaflac --show-md5sum "$fname" >>metasums`;
	}
}

`rm md5sums` if ( -f "md5sums" );

chdir($curdir);
}
