/**
 * File:
 *   read_routines.ycp
 *
 * Module:
 *   Sound
 *
 * Summary:
 *   Routines for reading sound card configuration
 *
 * Authors:
 *   Dan Meszaros <dmeszar@suse.cz>
 *
 * $Id: read_routines.ycp 16044 2004-03-11 16:40:35Z jsuchome $
 *
 */

{
    import "Sound";

    include "sound/routines.ycp";// for is_snd_alias()

    /**
     * tries to determine card model name from audio.alsa agent
     * @param card_id card id
     * @return card name, "Sound card" on failure
     */
    define string read_card_name_from_alsa(integer card_id) ``{
	path pth = topath(sformat(".audio.alsa.cards.%1.name", card_id));
	string name = (string) SCR::Read(pth);
	if (name == nil)
	{
	    return "Sound card";
	}
	return name;
    }


    /**
     * Extacts the unique key and the name of the card from comment in the
     * modules.conf placed before char-major-81-x
     * @param comment before the char-major-81-x
     * @return map example: $[ "unique_key" : string, "name" : string ] or nil
     */
    define map extractUniqueKey (string comment) ``{
	map result = nil;

	// split to lines
	list<string> comment_lines = splitstring (comment, "\n");

	// find last line with a ":"
	string line_with_uk = "";
	integer colon_pos_uk = nil;
	foreach(string line, comment_lines, ``{
	    integer c_pos = findfirstof (line, ":");
	    if (c_pos != nil)
	    {
		line_with_uk = line;
		colon_pos_uk = c_pos;
	    }
	});

	// did we find it?
	if (colon_pos_uk != nil)
	{
	    // extract name
	    string name = substring (line_with_uk, colon_pos_uk + 1,
				     size(line_with_uk) - colon_pos_uk - 1);
	    // extract unique key
	    integer start_uk = findfirstnotof (line_with_uk, "# \t");
	    string uk = substring (line_with_uk, start_uk,
				  colon_pos_uk - start_uk);

	    result = $[ "name" : name, "unique_key" : uk ];
	}
	return result;
    }


    /**
     * reads already saved info from given file
     * @return list
     */
    define list<map> read_modprobe (path mod_path) ``{

        list<map> save	= [];	// structure to save

	/*
	path mod_path	= .modprobe_sound;

	// read from /etc/modprobe/conf if /etc/modprobe.d/sound is not present
	if (SCR::Read(.target.size, "/etc/modprobe.d/sound") == -1)
	{
	    mod_path			= .modules;
	    Sound::used_modprobe_conf	= true;
	}
	*/

	path mod_alias	= add (mod_path, "alias");
	path mod_options= add (mod_path, "options");

	list<string> aliases = (list<string>) SCR::Read (mod_alias);

	aliases = filter(string a, aliases, ``(is_snd_alias(a)));

	// since parameters in modules options are separated by comas
	// (eg. options mod snd_id=1,2,3, snd_index=1,2,3),
	// we have to count occurences for each module
	integer position = -1;
	map mod_occur	= $[];			// alsa modules

	foreach (string a, aliases, ``{

	    position		= position + 1;
	    string modname	= (string) SCR::Read (add (mod_alias, a));
	    integer opt_pos	= mod_occur[modname]:0;

	    mod_occur	= add (mod_occur, modname, mod_occur[modname]:0 + 1);

	    map<string,string> opts = (map<string,string>)
		SCR::Read(add (mod_options, modname));
	    map options = $[];
	    foreach (string name, string val, opts, ``{
		list vals = splitstring(val, ",");
		if (size(val) > opt_pos)
		{
		    options = add (options, name, vals[opt_pos]:"");
		}
	    });

	    // read card info from the comment string
	    string comment = (string)
		SCR::Read(add (add (mod_alias,a), "comment"));
	    string uniq		= "";
	    string model	= "";
	    map res		= extractUniqueKey(comment);

	    if (res != nil)
	    {
		uniq	= res["unique_key"]:"";
		model	= res["name"]:"";
	    }
	    else
	    {
		// probably system upgrade
		uniq	= isa_uniq();
		model	= read_card_name_from_alsa (position);
	    }
	    map entry = $[
		"alias"		: a,
		"module"	: modname,
		"options"	: options,
		"unique_key"	: uniq,
		"model"		: model
	    ];
	    save = add (save, entry);
	});
        return save;
    }

    /**
     * reads already saved info from modules.conf
     * @example of return value:
     * [
     *	    $[
     *		"alias":    "snd-card-0",
     *		"module":   "snd-card-emu10k1",
     *		"options":  ["snd_id":"0", "snd_index":"card1"],
     *		"unique_key":"asdf.asdfasdfasdf",
     *		"model":    "Sound Blaster Live!"
     *	    ],
     *	    $[...]
     *	]
     * @return list
     */
    define list<map> read_save_info () ``{

	// First, read from /etc/modprobe.d/sound
        list<map> saved	= read_modprobe (.modprobe_sound);
	if (saved == [])
	{
	    // Nothing was there. So, try /etc/modprobe.conf...
	    saved	= read_modprobe (.modules);
	    if (saved != [])
	    {
		Sound::used_modprobe_conf	= true;
	    }
	}
	return saved;
    }

}//EOF
