#!/usr/bin/perl -w
#
# Copyright (c) 2010 Christopher Hofmann, Novell Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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 (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
#
# Service to create Driver Update Kiwi files
#
BEGIN {
  my ($wd) = $0 =~ m-(.*)/- ;
  $wd ||= '.';
  unshift @INC,  "$wd";
}

use strict;
use Getopt::Long qw(GetOptionsFromArray :config pass_through);
use Data::Dumper;
use XML::Structured ':bytes';
#use BSUtil;
use BSKiwiXML;

my $dtd = $BSKiwiXML::kiwidesc;

#my $bsdir;
#my $localarch;
#my $obsname;
#eval{
#  require BSConfig;
#  $bsdir = "$BSConfig::bsdir" if defined($BSConfig::bsdir);
#  $localarch = "$BSConfig::localarch" if defined($BSConfig::localarch);
#  $obsname = "$BSConfig::obsname" if defined($BSConfig::obsname);
#};

sub usage()
{
  print<<END

FIXME:
  generator_driver_update_disk product_file output_directory [project_name]

  convert a product definition file to a spec- and a kiwi source file.

  Options:

  -h:   help, print this text.
END
;

  exit;
}

sub parsePacklistXML {
    my $filename = shift;

    # read xml file
    open(my $fh, '<', $filename) or die $!;

    my $xml = '';
    while( my $line = <$fh> ) {
        $xml .= $line;
    }

    close $fh;

    # define xml schema
    my $binarylist = 
        [['binarylist' => 'package',
          [[ 'binary' =>
             'filename' ]],
         ]];

    my $packages = [ 'packlist',
                     [ 'repopackages', $binarylist ],
                     [ 'modules', $binarylist ],
                     [ 'instsys', $binarylist ]
        ];

    # parse xml file with defined schema
    my $packlist = XMLin($packages, $xml);

    # fill result into an hash
    my %packages = ();
    foreach my $element (qw(repopackages modules instsys)) {
        my @binaries = map { map {$_->{filename}} @{$_->{binary}} } @{$packlist->{$element}->{binarylist}};
        $packages{$element} = \@binaries;
    }

    return \%packages;
}

###

my $kiwi_repo = 'obs://openSUSE:11.4/standard';
my $distname = 'DriverUpdateDisk';
my $name = $distname;
my @archs;
my @instrepos;
my $vendor = 'vendor';
my $version = 'version';
my $packlist_file = './dud_packlist.xml';
my $outdir = './';
my $specification = $distname;

# Process the commandline arguments.
GetOptions(
    "name=s" => \$distname,
    "arch=s" => \@archs,
    "instrepo=s" => \@instrepos,
    "packlist=s" => \$packlist_file,
    "outdir=s" => \$outdir
    );

my $filename = $outdir.'/'.$distname.'.kiwi';
$filename =~ s/\s/_/g;
my $basearchs = join ' ', @archs;
push @instrepos, $kiwi_repo;

my $packlist = parsePacklistXML($packlist_file);
#print Dumper($packlist);
my @repo_binaries = @{$packlist->{repopackages}};
my @instsys_binaries = @{$packlist->{instsys}};
my @module_binaries = @{$packlist->{modules}};

#
# Create a kiwi config
#

my $kiwi = {
    'schemaversion' => '5.2',
    'name'          => 'bla',
    'description'   => {
        'specification' => $specification,
        'type'          => 'system',
        'author'        => 'The SUSE Team',
        'contact'       => 'build@opensuse.org'
    },
    'preferences' => {
        'version'        => '1.0.0',
        'type'           => [ { 'image' => 'product' } ],
        'packagemanager' => 'zypper'
    },
    'repository' => [
        {
            'source' => { 'path' => '/var/lib/empty' },
            'type'   => 'yast2'
        }
    ],
    'instsource' => {
        'repopackages' => [
            {
                'repopackage' => [
                    { 'name' => 'dummy1' },
                    { 'name' => 'dummy2' },
                ]
            }
        ],
        'metadata' => {
            'repopackage' => [
#                {
#                    'removearch' => 'src,nosrc',
#                    'onlyarch'   => 'i586,noarch',
#                    'medium'     => '0',
#                    'name'       => 'skelcd-openSUSE'
#                }
            ]
        },
        'architectures' => {
            #'requiredarch' => [ { 'ref' => 'x86_64' } ],
            'arch'         => [
                {
                    'name'     => 'dummy',
                    'id'       => 'i386',
                    'fallback' => 'noarch'
                },
                {
                    'name'     => 'dummy',
                    'id'       => 'i486',
                    'fallback' => 'i386'
                },
                {
                    'name'     => 'dummy',
                    'id'       => 'i586',
                    'fallback' => 'i486'
                },
                {
                    'name'     => 'dummy',
                    'id'       => 'i686',
                    'fallback' => 'i586'
                },
                {
                    'name' => 'dummy',
                    'id'   => 'noarch'
                },
                {
                    'name'     => 'dummy',
                    'id'       => 'x86_64',
                    'fallback' => 'i686'
                }
            ]
        },
        'driverupdate' => {
            'modules' =>
              [ { 'repopackage' => [ { 'name' => 'dummy' } ] } ],
            'instsys' =>
              [ { 'repopackage' => [ { 'name' => 'dummy' } ] } ],
            'target' => [
                {
                    '_content' => 'x86_64-sles10',
                    'arch'     => 'x86_64'
                }
            ],
            #'install' =>
            #  [ { 'repopackage' => [ { 'name' => 'dummy' } ] } ]
        },
        #'instrepo' => [
        #    {
        #        'source'   => { 'path' => 'obs://openSUSE:Factory/standard' },
        #        'priority' => 1,
        #        'name'  => 'repository_1',
        #        'local' => 'true'
        #    }
        #],
        'productoptions' => {
            'productvar' => [
                {
                    '_content' => $distname,
                    'name'     => 'DISTNAME'
                },
                {
                    '_content' => 'CD',
                    'name'     => 'FLAVOR'
                },
                {
                    '_content' => $distname,
                    'name'     => 'MEDIUM_NAME'
                },
                {
                    '_content' => 'no',
                    'name'     => 'MULTIPLE_MEDIA'
                },
                {
                    '_content' => '/',
                    'name'     => 'PRODUCT_DIR'
                },
                {
                    '_content' => '$DISTNAME-$FLAVOR',
                    'name'     => 'PRODUCT_NAME'
                },
                {
                    '_content' => 'suse',
                    'name'     => 'PRODUCT_THEME'
                },
                {
                    '_content' => '$VERSION',
                    'name'     => 'PRODUCT_VERSION'
                },
                {
                    '_content' => '-x',
                    'name'     => 'SHA1OPT'
                },
                {
                    '_content' => 'openSUSE',
                    'name'     => 'VENDOR'
                },
                {
                    '_content' => '11.1',
                    'name'     => 'VERSION'
                }
            ],
            'productoption' => [
                #{
                #    '_content' => 'RC 1',
                #    'name'     => 'BETA_VERSION'
                #},
                {
                    '_content' => '/usr/share/kiwi/modules/plugins/suse-11.1',
                    'name'     => 'INI_DIR'
                },
                {
                    '_content' => '/usr/share/kiwi/modules/plugins/suse-11.1',
                    'name'     => 'PLUGIN_DIR'
                },
                {
                    '_content' => '',
                    'name'     => 'REPO_LOCATION'
                },
                {
                    '_content' => 0,
                    'name'     => 'SOURCEMEDIUM'
                }
            ],
            'productinfo' => [
                {
                    '_content' => $basearchs,
                    'name'     => 'BASEARCHS'
                },
                {
                    '_content' => 'suse',
                    'name'     => 'DATADIR'
                },
                {
                    '_content' => 'suse/setup/descr',
                    'name'     => 'DESCRDIR'
                },
                {
                    '_content' => 'SUSE_SLE',
                    'name'     => 'DISTRIBUTION'
                },
                {
                    '_content' => $name,
                    'name'     => 'LABEL'
                },
                #{
                #    '_content' => 'en',
                #    'name' => 'LINGUAS'
                #},
                {
                    '_content' => $name,
                    'name'     => 'NAME'
                },
                {
                    '_content' => '',
                    'name'     => 'RELNOTESURL'
                },
                {
                    '_content' => 'SUSE LINUX Products GmbH, Nuernberg, Germany',
                    'name'     => 'VENDOR'
                },
                {
                    '_content' => '11.1',
                    'name'     => 'VERSION'
                }
            ]
        }
    }
};

# Create <target .../> and <requiredarch .../> section
my @arch_xml = ();
my @target_xml = ();
foreach my $arch (@archs) {
    my $target_str = $arch eq 'i586' ? 'i386' : $arch;
    push @target_xml, {arch => $arch, _content => $target_str.'-sles10'};
    push @target_xml, {arch => $arch, _content => $target_str.'-sled10'};
    push @arch_xml, { 'ref' => $arch };
}
$kiwi->{instsource}->{driverupdate}->{target} = \@target_xml;
$kiwi->{instsource}->{architectures}->{requiredarch} = \@arch_xml;

# Create <repopackages> section
my @repopackage_xml = ();
foreach my $repopackage (@repo_binaries) {
    foreach my $arch (@archs) {
        push @repopackage_xml, { name => $repopackage, arch => $arch };
    }
}
$kiwi->{instsource}->{repopackages}[0]->{repopackage} = \@repopackage_xml;

# Create <module> list
my @module_xml = @repopackage_xml;
#foreach my $module (@module_binaries) {
#    push @module_xml, { 'name' => $module };
#}
$kiwi->{instsource}->{driverupdate}->{modules}[0]->{repopackage} = \@module_xml;

# Create <instsys> list
my @instsys_xml = ();
foreach my $instsys (@instsys_binaries) {
    push @instsys_xml, { 'name' => $instsys };
}
$kiwi->{instsource}->{driverupdate}->{instsys}[0]->{repopackage} = \@instsys_xml;

# Create <instrepo> section
my @instrepos_xml = ();
my $count = 1;
foreach my $instrepo (@instrepos) {
    $instrepo = 'obs://'.$instrepo unless $instrepo =~ m|^\s*obs://|;
    push @instrepos_xml, {
        'source'   => { 'path' => $instrepo },
        'priority' => $count,
        'name'  => 'repository_'.$count,
        'local' => 'true' };
    $count++;
}
$kiwi->{instsource}->{instrepo} = \@instrepos_xml;

# Create XML
my $xml = XMLout($dtd, $kiwi);

# Write XML to file
open(my $fh,'>',$filename);
print $fh $xml;
close($fh);

print "Wrote $filename.\n";
