#
# ChrootInfo.pm: chroot utility library for sbuild
# Copyright © 2005-2009 Roger Leigh <rleigh@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#
#######################################################################

package Sbuild::ChrootInfoSchroot;

use Sbuild::ChrootInfo;
use Sbuild::ChrootSchroot;

use strict;
use warnings;

BEGIN {
    use Exporter ();
    our (@ISA, @EXPORT);

    @ISA = qw(Exporter Sbuild::ChrootInfo);

    @EXPORT = qw();
}

sub new {
    my $class = shift;
    my $conf = shift;

    my $self = $class->SUPER::new($conf);
    bless($self, $class);

    return $self;
}

sub get_info_from_stream {
    my $self = shift;
    my $stream = shift;

    my $chroot_type = '';
    my %tmp = ('Namespace' => '',
	       'Name' => '',
	       'Priority' => 0,
	       'Location' => '',
	       'Session Purged' => 0);

    while (<$stream>) {
	chomp;

	last if ! $_;

	if (/^\s*(───|---) Chroot \1$/ &&
	    $tmp{'Namespace'} eq "") {
	    $tmp{'Namespace'} = 'chroot';
	}
	if (/^\s*(───|---) Session \1$/ &&
	    $tmp{'Namespace'} eq "") {
	    $tmp{'Namespace'} = 'session';
	}
	if (/^\s*(───|---) Source \1$/ &&
	    $tmp{'Namespace'} eq "") {
	    $tmp{'Namespace'} = 'source';
	}
	if (/^\s*Name:?\s+(.*)$/ &&
	    $tmp{'Name'} eq "") {
	    $tmp{'Name'} = $1;
	}
	if (/^\s*Type:?\s+(.*)$/) {
	    $chroot_type = $1;
	}
	if (/^\s*Location:?\s+(.*)$/ &&
	    $tmp{'Location'} eq "") {
	    $tmp{'Location'} = $1;
	}
	if (/^\s*Mount Location:?\s+(.*)$/ &&
	    $tmp{'Location'} eq "") {
	    $tmp{'Location'} = $1;
	}
	# Path takes priority over Location and Mount Location.
	if (/^\s*Path:?\s+(.*)$/) {
	    $tmp{'Location'} = $1;
	}
	if (/^\s*Priority:?\s+(\d+)$/) {
	    $tmp{'Priority'} = $1;
	}
	if (/^\s*Session Purged\s+(.*)$/) {
	    if ($1 eq "true") {
		$tmp{'Session Purged'} = 1;
	    }
	}
	if (/^\s*Aliases:?\s+(.*)$/) {
	    $tmp{'Aliases'} = $1;
	}
    }

    if ($self->get_conf('DEBUG') && $tmp{'Name'})  {
	print STDERR "Found schroot chroot: $tmp{'Namespace'}:$tmp{'Name'}\n";
	foreach (sort keys %tmp) {
	    print STDERR "  $_ $tmp{$_}\n";
	}
    }

    if (!$tmp{'Name'}) {
	return undef;
    }
    return \%tmp;
}

sub get_info {
    my $self = shift;
    my $chroot = shift;

    my $chroot_type = "";

    # If namespaces aren't supported, try to fall back to old style session.
    open CHROOT_DATA, '-|', $self->get_conf('SCHROOT'), '--info', '--chroot', "session:$chroot" or
	open CHROOT_DATA, '-|', $self->get_conf('SCHROOT'), '--info', '--chroot', $chroot or
	die 'Can\'t run ' . $self->get_conf('SCHROOT') . ' to get chroot data';

    my $tmp = $self->get_info_from_stream(\*CHROOT_DATA);

    if (!$tmp) {
	close CHROOT_DATA;
	return undef;
    }

    close CHROOT_DATA or die "Can't close schroot pipe getting chroot data";

    return $tmp;
}

sub get_info_all {
    my $self = shift;

    my $chroots = {};

    local %ENV;

    $ENV{'LC_ALL'} = 'C';
    $ENV{'LANGUAGE'} = 'C';

    open CHROOTS, '-|', $self->get_conf('SCHROOT'), '--info'
	or die 'Can\'t run ' . $self->get_conf('SCHROOT');
    my $tmp = undef;
    while (defined($tmp = $self->get_info_from_stream(\*CHROOTS))) {
	my $namespace = $tmp->{'Namespace'};
	$namespace = "chroot"
	    if !$tmp->{'Namespace'};
	$chroots->{$namespace} = {}
	    if (!exists($chroots->{$namespace}));
	$chroots->{$namespace}->{$tmp->{'Name'}} = $tmp;
	foreach my $alias (split(/\s+/, $tmp->{'Aliases'})) {
	    $chroots->{$namespace}->{$alias} = $tmp;
	}
    }
    close CHROOTS or die "Can't close schroot pipe";

    $self->set('Chroots', $chroots);
}

sub _create {
    my $self = shift;
    my $chroot_id = shift;

    my $chroot = undef;

    if (defined($chroot_id)) {
	$chroot = Sbuild::ChrootSchroot->new($self->get('Config'), $chroot_id);
    }

    return $chroot;
}

1;
