#!/usr/bin/perl

# Copyright (C) 2005 Mandriva
#                    Olivier Blin <oblin@mandriva.com>
# Copyright (C) 2017-2018 Mageia
#                    Martin Whitaker <mageia@martin-whitaker.me.uk>
#
# 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, 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA.

use lib qw(/usr/lib/libDrakX);

use strict;

use MDK::Common;

use Getopt::Long;
use Pod::Usage;

use MGA::DrakISO::Config;
use MGA::DrakISO::LiveBuild;
use MGA::DrakISO::Utils;

use MGA::DrakISO::BuildRoot;
use MGA::DrakISO::BuildBoot;
use MGA::DrakISO::BuildLoop;
use MGA::DrakISO::BuildISO;

###############################################################################
# Globals
###############################################################################

$::verbose = 1;

###############################################################################
# Actions
###############################################################################

sub clean {
    my ($build) = @_;

    my $build_dir = $build->get_build_dir;
    if (-e $build_dir) {
        umount_all_in_root($build_dir);
        run_as_root('rm', '-rf', $build_dir);
    }
}

sub prepare_root {
    my ($build) = @_;
    install_live_system($build);
    customise_live_system($build);
}

sub prepare_boot {
    my ($build) = @_;
    prepare_live_system_boot($build);
    prepare_iso_bootloader($build);
}

###############################################################################
# Main Program
###############################################################################

my @actions = (
    { name => 'dump-config',    do => \&dump_config },
    { name => 'clean',          do => \&clean },
    { name => 'root',           do => \&prepare_root },
    { name => 'root-install',   do => \&install_live_system },
    { name => 'root-customise', do => \&customise_live_system },
    { name => 'boot',           do => \&prepare_boot },
    { name => 'boot-system',    do => \&prepare_live_system_boot },
    { name => 'boot-loader',    do => \&prepare_iso_bootloader },
    { name => 'loop',           do => \&build_live_loopback_file },
    { name => 'master',         do => \&build_iso },
);
my @all = qw(root boot loop master);

my $build_object  = 'MGA::DrakISO::LiveBuild'->new;
my $config_root   = '.';
my $config_path   = 'config/build.cfg';
my $settings_path = 'config/settings.cfg';

GetOptions(
    "help"              => sub { Pod::Usage::pod2usage('-verbose' => 1) },
    "all"               => sub { $_->{to_run} = 1 foreach grep { member($_->{name}, @all) } @actions },
    (map { $_->{name}   => \$_->{to_run} } @actions),
    "all-regions"       => sub { $build_object->{all_regions} = 1 },
    "config-root=s"     => \$config_root,
    "config=s"          => \$config_path,
    "settings=s"        => \$settings_path,
    "define=s"          => \%{$build_object->{settings}},
    "verbose=i"         => \$::verbose,
) or Pod::Usage::pod2usage();

require standalone;
    every { !$_->{to_run} } @actions and Pod::Usage::pod2usage();

    read_config($build_object, $config_root, $config_path, $settings_path);
    check_config($build_object);
    complete_config($build_object);

    foreach my $region ($build_object->{all_regions} ? sort(keys %{$build_object->{regions}}) : $build_object->{settings}{region}) {
        $region and print qq(=== proceeding with region "$region"\n);
        $build_object->{settings}{region} = $region;
        foreach (grep { $_->{to_run} } @actions) {
            print qq(* entering step "$_->{name}"\n);
            $_->{do}->($build_object);
            print qq(* step "$_->{name}" done\n);
        }
    }

__END__

###############################################################################
# Documentation
###############################################################################

=head1 NAME

draklive2 - A live distribution ISO mastering tool

=head1 SYNOPSIS

draklive2 [options]

 Options:
   --help            long help message

   --root            install and customise live system in chroot
   --boot            prepare system boot and ISO bootloader files
   --loop            build compressed loopback files
   --master          build master image

   --all             run all the above steps

   --clean           clean out the working directories

   --root-install    (for debug) run base install of live system
   --root-customise  (for debug) run system customisation steps

   --boot-system     (for debug) prepare kernel and initrd for system boot
   --boot-loader     (for debug) prepare bootloader for ISO

   --config-root <dir>
                     root directory containing config and additional files
                     defaults to current directory

   --config <file>   use this configuration file to control the build
                     defaults to "config/build.cfg"

   --settings <file> use this file as build settings (name=value format)
                     defaults to "config/settings.cfg"

   --define <name>=<value>
                     set setting <name> to <value>
                     takes precedence over values from a settings file

   --all-regions     proceed with all configured regions

   --verbose <level>
                     set verbosity level to <level>
                     defaults to 1

Examples:

 draklive2 --clean

 draklive2 --all

 draklive2 --config config/live.cfg --root

=head1 OPTIONS

=over 8

=item B<--config>

Makes B<draklive2> use the next argument as a configuration file. This file
should contain an associative array specifying the ISO composition. See
L<https://wiki.mageia.org/en/draklive2> for details.

=item B<--settings>

Makes B<draklive2> load the next argument as a file in name=value format into
the $build->{settings} associative array ($build being the global configuration
associative array). See L<https://wiki.mageia.org/en/draklive2> for details.

=back

=head1 DESCRIPTION

B<draklive2> builds a live distribution ISO according to a configuration file.

See L<https://wiki.mageia.org/en/draklive2>

=head1 AUTHORS

Olivier Blin <oblin@mandriva.com>
Martin Whitaker <mageia@martin-whitaker.me.uk>

=cut
