/*
 * File:
 *   lvm_lv.ycp
 *
 * Module:
 *
 * Summary:
 * main for lvm-configs logical volume management
 *
 * Authors:
 *   mike <mike@suse.de>
 *
 * $Id: inst_lvm_lv.ycp 19964 2004-10-26 15:37:35Z fehr $
 *
 *
 *----------------------------------------------------
 * IMPORTANT: when you read this code notice:
 *
 * vg  = volume group
 * vgs = volume groups
 *
 * pv  = physical volume
 * pvs = physical volumes
 *
 * lv  = logical volume
 * lvs = logical volumes
 *----------------------------------------------------
 *
 */

{



    textdomain "storage";

    import "Mode";
    import "Storage";
    import "Wizard";
    import "FileSystems";

    include "partitioning/lvm_lib.ycp";
    include "partitioning/lvm_lv_lib.ycp";
    include "partitioning/lvm_ui_dialogs.ycp";



    string  current_vg = "none";
    string  vg_key = "";
    integer pesize = 4*1024*1024;

    boolean test_mode        		= Mode::test ();
    map<string,map> targetMap        	= Storage::GetTargetMap();
    map<integer,map> modify_targets   	= (map<integer,map>)Storage::GetModifyTargets();
    boolean view_all_mnts    		= Storage::GetLvmViewAllMnt();

    ////////////////////////////////////////////////
    // Testmode, should be commented in release
    // test_mode   = true;
    // test_mode   = false;
    ////////////////////////////////////////////////


    // supported filesystems -> inst_disk.ycp > global

    list lvm_vgs = get_vgs( targetMap );
    list<map> parts = [];
    list table = [];

    if( size(lvm_vgs)<=0 )
	return( `next );

    // heading text
    Wizard::SetContents( _("Logical Volume Manager -- Logical Volumes"),
			 get_lv_content( [], lvm_vgs, "------------", view_all_mnts),
			 "", true, true);
    Wizard::SetHelpText( getLvHelptext() );



    //////////////////////////////////////////////////////////////////////
    // First we typically have to create a volumegroup
    // check if there is already a lvm group
    //////////////////////////////////////////////////////////////////////

    // Display current vg:
    current_vg = lvm_vgs[0]:"";
    vg_key = "/dev/" + current_vg;
    pesize = targetMap[vg_key,"cyl_size"]:(4*1024*1024);
    new_vg_list( lvm_vgs );
    UI::ChangeWidget( `id(`vg), `Value, current_vg);


    any vg = nil;


    //////////////////////////////////////////////////////////////////////
    // mainloop
    //////////////////////////////////////////////////////////////////////

    string  id          =  "";
    symbol  ret         = `next;
    integer max_size    = 0;
    integer used_size   = 0;
    list    size_list   = [];
    string  vg_size_str = "";

    repeat
    {

	/////////////////////////////////////////////////////////////////
	// Show the current state:

	parts = get_lvs_and_mounted_partitions( targetMap, view_all_mnts, 
	                                        current_vg );
	y2milestone( "parts=%1", parts );
	table = get_lv_widget_table( parts );
	y2milestone( "table=%1", table );
	UI::ChangeWidget( `id(`lv_table), `Items, table);

	parts = get_lvs_and_mounted_partitions( targetMap, false, current_vg );
	y2debug( "parts=%1 current_vg=%2", parts, current_vg );
	size_list = get_lv_size_info( targetMap, parts, current_vg );
	max_size  = size_list[1]:0;
	used_size = size_list[0]:0;
	y2debug( "list=%3, max_size=%1 used_size=%2", max_size, used_size, size_list );
	vg_size_str = ByteToHumanStringWithZero( max_size );

	if( UI::HasSpecialWidget( `BarGraph ))
	   {
	   UI::ChangeWidget( `id(`vg_size), `Labels,
			     [
			      sformat( "used\n%1", ByteToHumanStringWithZero(used_size)),
			      sformat( "free\n%1", ByteToHumanStringWithZero(max_size))
			     ] );
	   UI::ChangeWidget( `id(`vg_size), `Values, [ used_size / 1048576, max_size / 1048576 ] );
	}
	else
	{
	   UI::ChangeWidget( `id(`vg_size), `Value, vg_size_str);
	}


	if ( id != "" && id != nil )
	{
	    UI::ChangeWidget( `id(`lv_table), `CurrentItem, id);
	}


        /////////////////////////////////////////////////////////////////
        // Wait for User input
	ret = (symbol)Wizard::UserInput();
	y2milestone(" ret %1", ret );


	////////////////////////////////////////
	// user has changed the current volume group
	////////////////////////////////////////

	if ( ret == `vg )
	    {
	    current_vg = (string)UI::QueryWidget( `id(`vg), `Value);
	    vg_key = "/dev/" + current_vg;
	    pesize = targetMap[vg_key,"cyl_size"]:(4*1024*1024);
	    }



	////////////////////////////////////////
	// Add a new logical volume:
	////////////////////////////////////////


	if( ret == `viewmnt )
	    {
	    view_all_mnts = (boolean)UI::QueryWidget(`id(`viewmnt), `Value);
	    }


	////////////////////////////////////////
	// Add a new logical volume:
	////////////////////////////////////////


	if ( ret == `lv_add )
	    {
	    if( max_size<pesize )
		{
		// popup text %1 is replaced by a volume group name 
		Popup::Message(sformat(_("There is no available space in the current volume group %1"), current_vg ));
		}
	    else
		{
		map<string, any> Lv = $[
		       "create"		:	true,
		       "used_fs"	:	`reiser,
		       "lv_size"        :       max_size/4/pesize*pesize,
		       "stripes"	:	1,
		       "fs_options"	:	$[],
		       "format"		:	true,
		       "fsid"		:	Partitions::fsid_lvm,
		       "type"           :       `lvm,
		       "fstype"         :       "LV",
		       "mount"		:       
			   GetMountPointProposal( targetMap , 
			                          [ Partitions::BootMount() ] )
		    ];
		if( Lv["lv_size"]:0 == 0 )
		    {
		    Lv["lv_size"] = max_size/pesize*pesize;
		    }
		Lv["region"] = [ 0, (Lv["lv_size"]:0+pesize-1)/pesize ];
		Lv["size_byte"] = Lv["region",1]:0 * pesize;

		map createLv = DlgCreateEditLogicaVolume( "create",
							  Lv,
							  max_size,
							  current_vg,
							  get_lv_names(targetMap,current_vg),
							  FileSystems::GetAllFileSystems(true,true),
							  Stage::initial (),
							  "", pesize
							  );

		// has an error occured
		if ( size(createLv)>0 )
		    {
		    map ret = addLogicalVolume( createLv, modify_targets, 
						targetMap, current_vg );

		    targetMap      = ret["targets"]:targetMap;
		    modify_targets = ret["modify_targets"]:modify_targets;
		    Storage::SetModifyTargets( modify_targets );
		    Storage::SetTargetMap( targetMap );
		    }
		}
	    }

	////////////////////////////////////////
	// Edit/Resize a new logical volume:
	////////////////////////////////////////


	if( ret == `lv_edit || ret == `lv_table )
	    {
	    id = (string)UI::QueryWidget(`id(`lv_table), `CurrentItem);
	    y2milestone("id %1", id);

	    if( id == nil )
		{
		// Popup text
		Popup::Error(_("No device selected.
Select the device to edit.
"));
		}
	    else
		{
		map ret = HandleEditLv( targetMap, modify_targets, id );
		targetMap = ret["targets"]:targetMap;
		modify_targets = ret["modify_targets"]:modify_targets;
		Storage::SetModifyTargets( modify_targets );
		Storage::SetTargetMap( targetMap );
		}
	    }

	////////////////////////////////////////
	// Delete a new logical volume:
	////////////////////////////////////////

	if( ret == `lv_delete )
	    {
	    id = (string)UI::QueryWidget(`id(`lv_table), `CurrentItem);

	    if( id == nil )
		{
		// Popup text
		Popup::Error(_("No device selected.
Select the device to remove.
"));
		}
	    else
		{
		map ret = HandleRemoveLv( targetMap, modify_targets, id );
		targetMap      = ret["targets"]:targetMap;
		modify_targets = ret["modify_targets"]:modify_targets;
		Storage::SetModifyTargets( modify_targets );
		Storage::SetTargetMap( targetMap );
		}
	    }


	////////////////////////////////////////
	// Finish this step
	////////////////////////////////////////

	if( ret == `next || ret == `back )
	    {
	    Storage::SetLvmViewAllMnt( view_all_mnts );
	    }

    } until (ret == `next || ret == `back || ret == `cancel || ret == `abort );


    SCR::Write( .target.ycp, Storage::SaveDumpPath("targetMap_l"), targetMap );
    SCR::Write( .target.ycp, Storage::SaveDumpPath("modif"), modify_targets);

    return ret;
}


// end
