#! /usr/bin/perl -w

package Debconf::Client::ConfModuleX;

# Ripped right out of libapache-sessionx-perl, thanks to Angus Lees.

#
# Add the error checking behaviour that I think
# Debconf::Client::ConfModule should have anyway
#

use Debconf::Client::ConfModule;

use base qw(Exporter);

BEGIN {
  *EXPORT_OK = \@Debconf::Client::ConfModule::EXPORT_OK;
  *EXPORT_TAGS = \%Debconf::Client::ConfModule::EXPORT_TAGS;
}

sub AUTOLOAD {
  my $cmd = our $AUTOLOAD;
  $cmd =~ s|.*:||;

  my ($ret, $text) = &{"Debconf::Client::ConfModule::$cmd"}(@_);
  if ($ret == 0 or $ret >= 30 && $ret < 100) {
    # expected return values
    return wantarray ? ($ret, $text) : $text;
  }

  $cmd = uc $cmd;
  my $msg = $text ? "$text ($ret)" : "code $ret";

  require Carp;
  if ($ret < 10 || $ret >= 110) {
    Carp::confess("Debconf $cmd returned reserved error code? $msg");
  } elsif ($ret < 20) {
    # Dump @_ ?
    Carp::croak("Debconf $cmd: invalid parameters: $msg");
  } elsif ($ret < 30) {
    Carp::confess("Debconf $cmd: syntax error: $msg");
  } else { # $ret < 110
    Carp::confess("Debconf $cmd: debconf internal error: $msg");
  }
}

1;

package main;

sub move_file {
    my ($src, $dst) = @_;
    rename($src, $dst) or system("mv $src $dst");
}

BEGIN { Debconf::Client::ConfModuleX->import(qw(:all)) }

use strict;

version('2.0'); # We be a clever config!
capb('backup'); # We can even reverse parallel park!

my @alsa_modules = metaget("alsa-common/card-list", "choices");
my %alsa_modules_list = ();
foreach (split(/, /, $alsa_modules[1])) {
  /^([^\s]+)\s(.+)/;
  $alsa_modules_list{$1} = $2;
}
$alsa_modules_list{done} = "";

my @to_unregister = ("what_version_is_your_config", "move_config_to_new_location");
foreach (@to_unregister) {
  my @ret = Debconf::Client::ConfModule::get("alsa-base/$_");
  unregister("alsa-base/$_") if $ret[0] == 0;
}

if (-f "/etc/modutils/alsa" && ! -l "/etc/modutils/alsa") {
  move_file("/etc/modutils/alsa", "/etc/alsa/modutils/0.9");
}

my @alsa_file = ();
if (-f "/etc/alsa/modutils/0.9") {
  open(ALSAFILE, "</etc/alsa/modutils/0.9");
  @alsa_file = grep(/^\s*alias snd-card-/, <ALSAFILE>);
  close ALSAFILE;
}

my @file_cards_untouched = ();

foreach (@alsa_file) {
  my @cur_line = split(/\s/, $_);
  $cur_line[-1] =~ s/snd-//;
  push(@file_cards_untouched, $cur_line[-1]);
}
push(@file_cards_untouched, "done");

my @ret = get("alsa-base/card_list");
my @deb_cards_untouched = split(/ /, $ret[1]);

my @file_cards = ();
my @deb_cards = ();

# Remove duplicates.
if ($ARGV[1] ne "") {
  system("dpkg --compare-versions $ARGV[1] lt 0.9.2-6");
  if ($? == 0) {
    my %seen = ();
    foreach (@file_cards_untouched) {
      push(@file_cards, $_) unless $seen{$_}++;
    }
    %seen = ();
    foreach (@deb_cards_untouched) {
      push(@deb_cards, $_) unless $seen{$_}++;
    }
  } else {
    @deb_cards = @deb_cards_untouched;
    @file_cards = @file_cards_untouched;
  }
}

if (@file_cards != @deb_cards) {
  @file_cards = @deb_cards;
}

subst("alsa-base/current_card", "alsa_modules", $alsa_modules[1]);

my @selected_cards = ();

my $counter = 0;
my $cur_card = "";
while ($cur_card ne "done") {
  if (exists($file_cards[$counter])) {
    set("alsa-base/current_card", "$file_cards[$counter] $alsa_modules_list{$file_cards[$counter]}");
  } else {
    set("alsa-base/current_card", "done");
  }
  if ($counter == 0) {
    subst("alsa-base/current_card", "alsa_cards", "");
  } else {
    my $cur_join_list = join(' ', @selected_cards);
    subst("alsa-base/current_card", "alsa_cards", $cur_join_list);
  }
  input("medium", "alsa-base/current_card");
  my @go_return = go();
  @ret = get("alsa-base/current_card");
  if ($go_return[0] == 0) {
    if ($ret[0] == 0) {
      my @tmp = split(/ /, $ret[1]);
      push(@selected_cards, $tmp[0]);
      $cur_card = $tmp[0];
    }
    $counter++;
  } elsif ($go_return[0] == 30) {
    if ($counter > 0) {
      pop(@selected_cards);
      if ($#selected_cards > 0) {
	$cur_card = $selected_cards[-1];
      } else {
	$cur_card = "";
      }
      $counter--;
    } else {
      $cur_card = "";
    }
  }
}

my $joinedcards = "";
foreach (@selected_cards) {
  my @cur_line = split(/ /, $_);
  $joinedcards .= $cur_line[0] . " ";
}
$joinedcards =~ s/ $//;

set("alsa-base/card_list", $joinedcards);

my @alsabase = ();
my $filename = "";
if (-f "/etc/default/alsa") {
  $filename = "/etc/default/alsa";
} elsif (-f "/etc/alsa/alsa-base.conf") {
  $filename = "/etc/alsa/alsa-base.conf";
} elsif (-f "/etc/alsa-base.conf") {
  $filename = "/etc/alsa-base.conf";
}
if ($filename ne "") {
  open(BASECONF, "<$filename");
  @alsabase = <BASECONF>;
  close BASECONF;
}

my $tmp_set = "";
foreach (@alsabase) {
  if (/^startosslayer=(.*)$/) {
    if (!$1) {
      $tmp_set = "false";
    } else {
      $tmp_set = "true";
    }
    set("alsa-base/start_oss_layer", $tmp_set);
  } elsif (/^force_stop_modules_before_suspend=(.*)$/) {
	$tmp_set = $1;
    set("alsa-base/force_stop_alsa_before_suspend", $tmp_set);
  } elsif (/^alsactl_store_on_shutdown=(.*)$/) {
    $tmp_set = $1;
    set("alsa-base/alsactl_store_on_shutdown", $tmp_set);
  }
}

input("low", "alsa-base/start_oss_layer");
input("low", "alsa-base/force_stop_alsa_before_suspend");
input("low", "alsa-base/alsactl_store_on_shutdown");
go();

