/**
 * File:	clients/nfs.ycp
 * Package:	Configuration of NFS
 * Summary:	Main file
 * Authors:
 *   Jan Holesovsky <kendy@suse.cz>
 *   Dan Vesely <dan@suse.cz>
 *   Martin Vidner <mvidner@suse.cz>
 *
 * $Id: nfs.ycp 21326 2005-02-07 15:43:58Z mvidner $
 *
 * Main file for nfs configuration. Uses all other files.
 */

{

/***
 * <h3>Configuration of NFS</h3>
 */

textdomain "nfs";

/* The main () */
y2milestone ("----------------------------------------");
y2milestone ("NFS module started");

import "Nfs";
import "Progress";
import "Report";
import "String";
import "Summary";

import "CommandLine";

include "nfs/wizards.ycp";

// handler for nfs summary
boolean NfsListHandler (map options) {


    list<map<string,any> > nfs_entries = Nfs::nfs_entries;
    if (size (nfs_entries) < 1)
    {
	CommandLine::Print (Summary::NotConfigured ());
	return false;
    }
    list<list<string> > items	= [];
    foreach (term i, FstabTableItems (nfs_entries), {
	items = add (items, [i[1]:"", i[2]:"", i[3]:"", i[4]:""]);
    });

    CommandLine::Print (String::TextTable ([
	   _("Server")+"  ",
	   _("Remote filesystem")+"  ",
	   _("Mountpoint")+"  ",
	   _("Options")+"  "
	], items, $[])
    );
    return false;
}

boolean NfsAddHandler (map options) {

    list<map<string,any> > nfs_entries = Nfs::nfs_entries;

    list specl		= splitstring (options["spec"]:"", ":");
    string server	= specl[0]:"";
    string pth		= specl[1]:"";
    string mount	= options["file"]:"";
    list<map> existing	= (list<map>) union (Nfs::non_nfs_entries, nfs_entries);

    if (!CheckHostName (server) || !CheckPath (pth) ||
	!CheckPath (mount) || IsMpInFstab (existing, mount))
	return false;

    if (! haskey (options, "mntops"))
	options["mntops"]	= "defaults";

    string options_error = check_options (options["mntops"]:"");
    if (size (options_error) > 0)
    {
	Report::Error (options_error);
	return false;
    }

    nfs_entries = add (nfs_entries, (map<string,any>) options);
    Nfs::nfs_entries = nfs_entries;
    return true;
}

boolean NfsEditHandler (map options) {

    list<map<string,any> > nfs_entries = Nfs::nfs_entries;

    string spec	= options["spec"]:"";
    string file	= options["file"]:"";

    if (spec == "" && file == "")
    {
	// error
	CommandLine::Print (_("No NFS mount specified."));
	return false;
    }
    list<integer> entries	= [];
    integer i			= 0;
    foreach (map<string,any> entry, nfs_entries, {
	if (entry["spec"]:"" == spec || entry["file"]:"" == file)
	{
	    entries	= add (entries, i);
	    y2internal ("to change: %1", entry);
	}
	i = i + 1;
    });
    if (size (entries) == 0)
    {
	// error message
	CommandLine::Print (_("No NFS mount matching the criteria found."));
	return false;
    }
    if (size (entries) > 1)
    {
	list<list<string> > items	= [];
	foreach (term i, FstabTableItems (nfs_entries), {
	    items = add (items, [i[1]:"", i[2]:"", i[3]:"", i[4]:""]);
	});

	// error message
	CommandLine::Print (_("Multiple NFS mounts match the criteria:"));
	foreach (integer e, entries, {
	    map entry	= nfs_entries[e]:$[];
	    CommandLine::Print (
		sformat("spec=%1, file=%2", entry["spec"]:"",entry["file"]:""));
	});
	return false;
    }

    // now edit existing entry and check the validity
    integer entryno	= entries[0]:0;
    map entry		= union (nfs_entries[entryno]:$[], options);

    list specl		= splitstring (entry["spec"]:"", ":");
    string server	= specl[0]:"";
    string pth		= specl[1]:"";
    string mount	= entry["file"]:"";
    list<map> existing	= (list<map>)
	union (Nfs::non_nfs_entries, remove (nfs_entries, entryno));

    if (!CheckHostName (server) || !CheckPath (pth) ||
	!CheckPath (mount) || IsMpInFstab (existing, mount))
	return false;

    string options_error = check_options (entry["mntops"]:"");
    if (size (options_error) > 0)
    {
	Report::Error (options_error);
	return false;
    }

    nfs_entries[entryno]	= (map<string,any>) entry;
    Nfs::nfs_entries		= nfs_entries;
    return true;
}

boolean NfsDeleteHandler (map options) {

    list<map<string,any> > nfs_entries = Nfs::nfs_entries;

    string spec	= options["spec"]:"";
    string file	= options["file"]:"";

    if (spec == "" && file == "")
    {
	// error
	CommandLine::Print (_("No NFS mount specified."));
	return false;
    }
    boolean deleted	= false;
    nfs_entries	= filter (map<string,any> entry, nfs_entries, {
	if ((spec != "" && entry["spec"]:"" != spec) ||
	    (file != "" && entry["file"]:"" != file))
	    return true;
	else
	{
	    deleted = true;
	    return false;
	}
    });

    Nfs::nfs_entries = nfs_entries;
    return deleted;
}

map cmdline_description = $[
    "id"	: "nfs",
    /* Command line help text for the nfs module */
    "help"	: _("Configuration of NFS client"),
    "guihandler"        : NfsSequence,
    "initialize"        : Nfs::Read,
    "finish"            : Nfs::Write,
    "actions"           : $[
	"list"		: $[ // TODO summary is probably better...
	    "handler"	: NfsListHandler,
	    // command line action help
	    "help"	: _("List configured NFS mounts"),
	    ],
	"add"		: $[
	    "handler"	: NfsAddHandler,
	    // command line action help
	    "help"	: _("Add an NFS mount"),
	    ],
	"edit"		: $[
	    "handler"	: NfsEditHandler,
	    // command line action help
	    "help"	: _("Edit an NFS mount"),
	    ],
	"delete"	: $[
	    "handler"	: NfsDeleteHandler,
	    // command line action help
	    "help"	: _("Delete an NFS mount"),
	    ],
    ],
    "options"		: $[
	// TODO adjust names? create comaptibility aliases?
	"spec"		: $[
	    "type"	: "string", // host:path
	    // command line option help
	    // fstab(5): fs_spec
	    "help"	: _("Remote file system (in the form 'host:path')"),
	    ],
	"file"		: $[
	    "type"	: "string", // path
	    // command line option help
	    // fstab(5): fs_file
	    "help"	: _("Local mount point"),
	    ],
	// use defaults when not specified? describe in help?
	"mntops"	: $[
	    "type"	: "string", // a list?
	    // command line option help
	    // fstab(5): fs_mntops
	    "help"	: _("Mount options"),
	    ],
    ],
    "mappings"		: $[
	"list"		: [],
	"add"		: ["spec", "file", "mntops",],
	// either of spec and file is key
	"edit"		: ["spec", "file", "mntops",],
	// either of spec and file is key
	"delete"	: ["spec", "file",],
    ]
];

/* main ui function */
any ret = nil;

ret = CommandLine::Run(cmdline_description);
y2debug("ret=%1", ret);

/* Finish */
y2milestone("NFS module finished");
y2milestone("----------------------------------------");

return ret;

/* EOF */
}
