#!/usr/bin/perl

use strict;
use warnings;

use Snap;

setup();

my $conf = readconf();
my $templates = templates( $conf );
my $sources = Snap::Sources->new( $conf->{'sources'} );
my @packages = ();
my $template;

if ( ! Snap->TARGET ) {
	Snap->error( -1, 'A target must be specified with -t' );
	}

$template = $ARGV[0];
$sources->readpkgs();

foreach my $pkgname ( @{$templates->{$template}{'packages'}} ) {
	my $package = $sources->search( { name => $pkgname, quiet => 1 } );

	if ( $package->{'status'} && $package->{'status'} eq 'installed' ) {
		next;
		}

	if ( $package->{'path'} =~ /https*:\/\// ) {
		( my $filename = $package->{'path'} ) =~ s/.*\///;

		if ( -f "/var/lib/snap/packages/$filename" ) {
			$package->{'path'} = "/var/lib/snap/packages/$filename";
			}
		elsif ( -f Snap->PKGDIR . "/$filename" ) {
			$package->{'path'} = Snap->PKGDIR . "/$filename";
			}
		elsif ( ! -f Snap->PKGDIR . "/$filename" ) {
			Snap->httpget( $package->{'path'},
				Snap->PKGDIR . "/$filename", 0644 );

			$package->{'path'} = Snap->PKGDIR . "/$filename";
			}
		else {
			Snap->error( -1, "$package->{'name'}:"
				. " Unable to determine package path" );
			}
		}

	push( @packages, $package );
	}

foreach my $package ( @packages ) {
	$package->files( { quiet => 1 } );

	print "\n";

	$package->install();
	}

if ( ! @packages ) {
	print "Nothing to do\n";
	}
else {
	my $rootfs = "$conf->{'snapinstall'}{'templatedir'}/$template/rootfs";
	my $postinst = "$conf->{'snapinstall'}{'templatedir'}"
		. "/$template/postinst";
	my $pid;
	my $stat;

	if ( ! Snap->dirempty( $rootfs ) ) {
		if ( $pid = fork() ) {
			waitpid( $pid, 0 );
			$stat = $? >> 8;
			}
		else {
			exec( "cp -a '$rootfs'/* " . Snap->TARGET );
			}

		if ( $stat ) {
			Snap->error( $stat, "Failed to copy rootfs" );
			}
		}

	print "Setting root password\n";

	virtfs( 'mount' );

	if ( $pid = fork() ) {
		waitpid( $pid, 0 );
		$stat = $? >> 8;
		}
	else {
		if ( $> ) {
			exec( "fakeroot fakechroot /usr/sbin/chroot "
				. Snap->TARGET . " passwd root" );
			}
		else {
			exec ( "chroot " . Snap->TARGET . " passwd root" );
			}
		}

	virtfs( 'umount' );

	if ( $stat ) {
		Snap->error( $stat, "Failed to set password" );
		}

	if ( -f $postinst ) {
		my $tmpscript = "/var/lib/snap/postinst";

		open( my $fh, '<', $postinst ) || Snap->error( int( $! ),
			"Failed to open $postinst" );
		open( my $wh, '>', Snap->TARGET . "/$tmpscript" ) ||
			Snap->error( int( $! ), "Failed to open $tmpscript" );

		while ( <$fh> ) {
			print $wh $_;
			}

		close( $wh );
		close( $fh );

		if ( $pid = fork() ) {
			waitpid( $pid, 0 );
			$stat = $? >> 8;
			}
		else {
			if ( $> ) {
				exec( "fakeroot fakechroot /usr/sbin/chroot "
					. Snap->TARGET . " $tmpscript" );
				}
			else {
				exec ( "chroot " . Snap->TARGET
					. " $tmpscript" );
				}
			}

		if ( $stat ) {
			Snap->error( $stat, "Failed to execute $tmpscript" );
			}
		}
	}
