/**
 * File:	include/power-management/commandline.ycp
 * Package:	Configuration of power-management
 * Summary:	Command-line interface
 * Authors:	Jiri Srain <jsrain@suse.cz>
 *
 * $Id: commandline.ycp 21402 2005-02-08 10:20:33Z jsrain $
 *
 */

{

import "CommandLine";
import "DhcpServer";
import "NetworkDevices";

textdomain "dhcp-server";

include "dhcp-server/misc.ycp";

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
define boolean StatusHandler (map options) {
    CommandLine::Print (DhcpServer::GetStartService ()
	// status information for command line
	? _("DHCP server is enabled.")
	// status information for command line
	: _("DHCP server is disabled.")
    );
    return false;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
define boolean EnableHandler (map options) {
    DhcpServer::SetStartService (true);
    return true;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
define boolean DisableHandler (map options) {
    DhcpServer::SetStartService (false);
    return true;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
define boolean HostHandler (map options) {
    list<string> ifaces = DhcpServer::GetAllowedInterfaces ();
    // we assume there is only a single interface at this stage
    string interface = ifaces[0]:nil;

    map m = DhcpServer::GetInterfaceInformation (interface);
    string hosts_parent_id = m["network"]:"" + " netmask " + m["netmask"]:"";
    y2milestone ("Id to take hosts from: %1", hosts_parent_id );
    if (! DhcpServer::EntryExists ("subnet", hosts_parent_id) )
    {
	DhcpServer::CreateEntry ("subnet", hosts_parent_id, "", "" );
    }

    if (haskey(options, "list"))
    {
	boolean printed = false;
	list< map<string,string> > children
	    = DhcpServer::GetChildrenOfEntry ("subnet", hosts_parent_id);
	foreach (map<string,string> child, children, {
	    if (child["type"]:nil == "host")
	    {
		if (printed)
		    CommandLine::Print ("");
		string host = child["id"]:"";
		list< map<string,string> > directives
		    = DhcpServer::GetEntryDirectives ("host", host);
		// command-line text output, %1 is host name
		CommandLine::Print (sformat (_("Host: %1"), host));
		foreach (map<string,string> opt, directives, {
		    if( opt["key"]:nil == "hardware" )
		    {
			// command-line text output, %1 is hardwarre address
			// and hardware type (eg. "ethernet 11:22:33:44:55:66")
			CommandLine::Print (sformat (_("Hardware: %1"),
			    opt["value"]:""));
		    }
		    else if (opt["key"]:nil == "fixed-address")
		    {
			// command-line text output, %1 is IP address
			CommandLine::Print (sformat (_("IP Address: %1"),
			    opt["value"]:""));
		    }
		});
		printed = true;
	    }
	});
	return false;
    }

    string name = (string)options["name"]:nil;
    if (name == nil)
    {
	// command-line error report
	CommandLine::Error (_("Host name not specified."));
	return false;
    }


    if (haskey (options, "add") || haskey (options, "edit"))
    {
	if (haskey (options, "add"))
	{
	    DhcpServer::CreateEntry ("host", name, "subnet", hosts_parent_id);
	}
	else if (! DhcpServer::EntryExists ("host", name))
	{
	    // command-line error report
	    CommandLine::Error (_("Specified host does not exist."));
	    return false;
	}
	list <map<string,string> > directives
	    = DhcpServer::GetEntryDirectives ("host", name);
	if (haskey (options, "hardware-address")
	    && haskey (options, "hardware-type"))
	{
	    directives = filter (map<string,string>d, directives,
		{return d["key"]:"" != "hardware";});
	    string val = sformat ("%1 %2", options["hardware-type"]:"",
		options["hardware-address"]:"");
	    directives = add (directives,
		$[ "key" : "hardware", "value" : val]);
	}
	if (haskey (options, "ip-address"))
	{
	    directives = filter (map<string,string>d, directives,
		{return d["key"]:"" != "fixed-address";});
	    directives = add (directives,
		$["key" : "fixed-address", "value" : options["ip-address"]:""]);
	}

	DhcpServer::SetEntryDirectives ("host", name, directives);
	return true;
    }

    if (haskey (options, "delete"))
    {
	DhcpServer::DeleteEntry ("host", name);
	return true;
    }
    return false;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
boolean InterfaceHandler (map options) {
    NetworkDevices::Read ();
    list<string> all_interfaces = NetworkDevices::List ("");
    all_interfaces = filter (string i, all_interfaces, {
	return i != "lo";
    });
    list<string> dhcp_ifaces = DhcpServer::GetAllowedInterfaces ();
    list<string> other_ifaces = filter (string i, all_interfaces, {
	return ! contains (dhcp_ifaces, i);
    });
    if (haskey (options, "current"))
    {
	string selected = mergestring (dhcp_ifaces, ", ");
	string other = mergestring (other_ifaces, ", ");
	if (selected == "")
	    // to be eventually pasted to "Selected interfaces: %1"
	    selected = _("none");
	if (other == "")
	    // to be eventually pasted to "Other interfaces: %1"
	    other = _("none");
	// command-line text output, %1 is list of network interfaces
	CommandLine::Print (sformat (_("Selected Interfaces: %1"), selected));
	// command-line text output, %1 is list of network interfaces
	CommandLine::Print (sformat (_("Other Interfaces: %1"), other));
	return false;
    }
    if (haskey (options, "select"))
    {
	string old_iface = dhcp_ifaces[0]:"";
	string new_iface = options["select"]:"";
	if (! contains (all_interfaces, new_iface))
	{
	    // command-line error report
	    CommandLine::Print (_("Specified interface does not exist."));
	    return false;
	}
	if (old_iface != "")
	    UpdateSubnetDeclaration (old_iface, new_iface);
	DhcpServer::SetAllowedInterfaces ([new_iface]);
	DhcpServer::SetModified ();
	return true;
    }
    // command-line error report
    CommandLine::Print (_("Operation with the interface not specified."));
    return false;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
boolean OptionsHandler (map options) {
    if (haskey (options, "print"))
    {
	// get the global options
	list<map<string,string> > options = DhcpServer::GetEntryOptions ("","");
	if ( options == nil )
	    options = [];

	foreach ( map<string,string> opt, options, {
	    string key = opt["key"]:"";
	    string value = opt["value"]:"";
	    CommandLine::Print (sformat ("%1 = %2", key, value));
	});
	return false;
    }
    if (haskey (options, "set"))
    {
	string key = options["key"]:"";
	string value = options["value"]:"";
	if (key == "")
	{
	    // command-line error report
	    CommandLine::Print (_("Option key must be set."));
	    return false;
	}
	if (value == "")
	{
	    // command-line error report
	    CommandLine::Print (_("Value must be set."));
	    return false;
	}
	list<map<string,string> > options = DhcpServer::GetEntryOptions ("","");
	if ( options == nil )
	    options = [];
	options = filter (map<string,string> o, options, {
	    return o["key"]:"" != key;
	});
	options = add (options, $[
	    "key" : key,
	    "value" : value,
	]);
	DhcpServer::SetEntryOptions ("", "", options);
	return true;
    }
    return false;
}

/**
  * Handler for command line interface
  * @param options map options from the command line
  * @return boolean true if settings have been changed
  */
boolean SubnetHandler (map options) {
    list<string> ifaces = DhcpServer::GetAllowedInterfaces ();
    if ( size(ifaces) == 0 )
    {
	y2error ("No interfaces set");
	return false;
    }
    string interface = ifaces[0]:nil;
    map m = DhcpServer::GetInterfaceInformation (interface);
    string id = m["network"]:"" + " netmask " + m["netmask"]:"";
    y2milestone ("Id to lookup: %1", id );
    if (! DhcpServer::EntryExists ("subnet", id) )
    {
	DhcpServer::CreateEntry ("subnet", id, "", "" );
    }
    list < map< string,string> > directives
	= DhcpServer::GetEntryDirectives ( "subnet", id );
    if (directives == nil)
	directives = [];

    if (haskey (options, "print"))
    {
	foreach (map<string,string> opt, directives, {
	    if ( opt["key"]:nil == "range" )
	    {
		list<string> range = splitstring ( opt["value"]:"", " " );
		// command-line output text, %1  and %1 are IP addresses
		CommandLine::Print (sformat (_("Address Range: %1 - %2"),
		     range[0]:"", range[1]:""));
	    }
	    else if ( opt["key"]:nil == "default-lease-time" )
	    {
		// command-line output text, %1 is integer
		CommandLine::Print (sformat (_("Default Lease Time: %1"),
		    opt["value"]:nil));
	    }
	    else if ( opt["key"]:nil == "max-lease-time" )
	    {
		// command-line output text, %1 is integer
		CommandLine::Print (sformat (_("Maximum Lease Time: %1"),
		    opt["value"]:nil));
	    }
	});
	return false;
    }

    boolean save = false;
    foreach (string key, ["default-lease-time", "max-lease-time"], {
	if (haskey (options, key))
	{
	    save = true;
	    directives = filter (map<string,string> d, directives, {
		return d["key"]:"" != key;
	    });
	    directives = add (directives, $[
		"key" : key,
		"value" : options[key]:"",
	    ]);
	}
    });
    if (haskey (options, "min-ip") || haskey (options, "max-ip"))
    {
	save = true;
	string range = "";
	directives = filter (map<string,string> d, directives, {
	    if (d["key"]:"" == "range")
	    {
		range = d["value"]:"";
		return false;
	    }
	    return true;
	});
y2error ("Range: %1", range);
	list<string> range_l = splitstring (range, " ");
y2error ("Range: %1", range_l);
	if (haskey (options, "min-ip"))
	    range_l[0] = options["min-ip"]:"";
	if (haskey (options, "max-ip"))
	    range_l[1] = options["max-ip"]:"";
	range = mergestring (range_l, " ");
y2error ("Range: %1", range);
	directives = add (directives, $[
	    "key" : "range",
	    "value" : range,
	]);
    }
    if (save)
    {
	DhcpServer::SetEntryDirectives ("subnet", id, directives);
	return true;
    }

    return false;
}

map cmdline = $[
   "id"			: "dhcp-server",
    // command line help text for NTP client module
    "help"		: _("DHCP server configuration module."),
    "guihandler"	: GuiHandler,
    "initialize"	: DhcpServer::Read,
    "finish"		: DhcpServer::Write,
    "actions" : $[
	"status" : $[
	    "handler"	: StatusHandler,
	    // command line help text for an action
	    "help"	: _("Print the status of the DHCP server"),
	],
	"enable" : $[
	    "handler"	: EnableHandler,
	    // command line help text for an action
	    "help"	: _("Enable the DHCP server"),
	],
	"disable" : $[
	    "handler"	: DisableHandler,
	    // command line help text for an action
	    "help"	: _("Disable the DHCP server"),
	],
	"host" : $[
	    "handler"	: HostHandler,
	    // command line help text for an action
	    "help"	: _("Manage individual host settings"),
	],
	"interface" : $[
	    "handler"	: InterfaceHandler,
	    // command line help text for an action
	    "help"	: _("Select the network interface to listen to"),
	],
	"options" : $[
	    "handler"	: OptionsHandler,
	    // command line help text for an action
	    "help"	: _("Manage global DHCP options"),
	],
	"subnet" : $[
	    "handler"	: SubnetHandler,
	    // command line help text for an action
	    "help"	: _("Manage DHCP subnet options"),
	],
    ],

    "options"       : $[
	"list" : $[
	    // command line help text for an option
	    "help"	: _("List all defined hosts with a fixed address"),
	],
	"add" : $[
	    // command line help text for an option
	    "help"	: _("Add a new host with a fixed address"),
	],
	"edit" : $[
	    // command line help text for an option
	    "help"	: _("Edit a host with a fixed address"),
	],
	"delete" : $[
	    // command line help text for an option
	    "help"	: _("Delete a host with a fixed address"),
	],
	"name" : $[
	    // command line help text for an option
	    "help"	: _("The name of the host with a fixed address"),
	    "type"	: "string",
	],
	"hardware-address" : $[
	    // command line help text for an option
	    "help"	: _("The hardware address of the host with a fixed address"),
	    "type"	: "string",
	],
	"hardware-type" : $[
	    // command line help text for an option
	    "help"	: _("The hardware type of the host with a fixed address"),
	    "type"	: "enum",
	    "typespec"	: ["ethernet", "token-ring"],
	],
	"ip-address" : $[
	    // command line help text for an option
	    "help"	: _("The IP address (or host name) of the host with a fixed address"),
	    "type"	: "string",
	],
	"list" : $[
	    // command line help text for an option
	    "help"	: _("List all defined hosts with a fixed address"),
	],
	"select" : $[
	    // command line help text for an option
	    "help"	: _("Select the network interface to use"),
	    "type"	: "string",
	],
	"current" : $[
	    // command line help text for an option
	    "help"	: _("Print the currently used interface and list other available interfaces"),
	],
	"print" : $[
	    // command line help text for an option
	    "help"	: _("Print current options"),
	],
	"set" : $[
	    // command line help text for an option
	    "help"	: _("Set a global option"),
	],
	"key" : $[
	    // command line help text for an option
	    "help"	: _("Option key (e.g., ntp-servers)"),
	    "type"	: "string",
	],
	"value" : $[
	    // command line help text for an option
	    "help"	: _("Option value (e.g., IP address)"),
	    "type"	: "string",
	],
	"min-ip" : $[
	    // command line help text for an option
	    "help"	: _("Lowest IP address of the dynamic address assigning range"),
	    "type"	: "ip4",
	],
	"max-ip" : $[
	    // command line help text for an option
	    "help"	: _("Highest IP address of the dynamic address assigning range"),
	    "type"	: "ip4",
	],
	"default-lease-time" : $[
	    // command line help text for an option
	    "help"	: _("Default lease time in seconds"),
	    "type"	: "integer",
	],
	"max-lease-time" : $[
	    // command line help text for an option
	    "help"	: _("Maximum lease time in seconds"),
	    "type"	: "integer",
	],
    ],

    "mappings"      : $[
	"status"	: [],
	"enable"	: [],
	"disable"	: [],
	"host"		: ["add", "edit", "delete", "list", "name",
			   "hardware-address", "hardware-type", "ip-address"],
	"interface"	: ["select", "current"],
	"options"	: ["print", "set", "key", "value"],
	"subnet"	: ["print", "min-ip", "max-ip", "default-lease-time",
			   "max-lease-time"],
    ],
];

/* EOF */
}
