#ifndef DEBTAGS_COMMANDLINE_H
#define DEBTAGS_COMMANDLINE_H

/*
 * Commandline parser for tagcoll
 *
 * Copyright (C) 2003--2012  Enrico Zini
 * 
 * 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <wibble/commandline/parser.h>

struct DebtagsOptions : public wibble::commandline::StandardParserWithMandatoryCommand
{
public:
    wibble::commandline::BoolOption* out_quiet;
	wibble::commandline::BoolOption* out_verbose;

	wibble::commandline::BoolOption* out_names;
	wibble::commandline::BoolOption* out_debug;
	wibble::commandline::BoolOption* out_facets;
	wibble::commandline::BoolOption* out_short;
	wibble::commandline::BoolOption* out_full;

	wibble::commandline::BoolOption* match_invert;

	wibble::commandline::BoolOption* misc_local;
	wibble::commandline::BoolOption* misc_reindex;
	wibble::commandline::IntOption* misc_distance;
	wibble::commandline::StringOption* misc_vocfile;

	wibble::commandline::BoolOption* smse_reltags;
	wibble::commandline::BoolOption* smse_disctags;

	wibble::commandline::Engine* update;
	wibble::commandline::Engine* check;
	wibble::commandline::Engine* tagcat;
	wibble::commandline::Engine* tagshow;
	wibble::commandline::Engine* tagsearch;
	wibble::commandline::Engine* show;
	wibble::commandline::Engine* cat;
	wibble::commandline::Engine* dumpavail;
	wibble::commandline::Engine* search;
	wibble::commandline::Engine* grep;
	wibble::commandline::Engine* install;
	wibble::commandline::Engine* diff;
	wibble::commandline::Engine* tag;
	wibble::commandline::Engine* submit;
	wibble::commandline::Engine* vocfilter;

	DebtagsOptions()
		: StandardParserWithMandatoryCommand("debtags", VERSION, 1, "enrico@enricozini.org")
	{
        using namespace wibble::commandline;

        usage = "<command> [options and arguments]";
        description = "Command line interface to access and manipulate Debian Package Tags";
        // Other options
        // OptionGroup* generalOpts = createGroup("General options");
        out_verbose = add<BoolOption>("verbose", 'v',
                "verbose", "", "enable verbose output");
        out_debug = add<BoolOption>("debug", 0, "debug", "",
                "enable debugging output (including verbose output)");

        // Create the collection output group
        OptionGroup* collOutputOpts = createGroup("Options controlling transformations of tag data on output");
        out_facets = collOutputOpts->add<BoolOption>("facets", 0, "facets", "",
                        "output only the names of the facets (mainly used for computing statistics)");
        out_names = collOutputOpts->add<BoolOption>("names", 0, "names", "",
                        "output only the names of the packages");
        out_quiet = collOutputOpts->add<BoolOption>("quiet", 'q', "quiet", "",
                        "do not write anything to standard output");

        // Create the package output group
        OptionGroup* pkgOutputOpts = createGroup("Options controlling transformations of package data on output");
        pkgOutputOpts->add(out_names);
        pkgOutputOpts->add(out_quiet);
        out_full = pkgOutputOpts->add<BoolOption>("full", 0, "full", "",
                        "output the full record of package data");
        out_short = pkgOutputOpts->add<BoolOption>("short", 0, "short", "",
                        "output the names of the packages, plus a short description");

		// Create the matching options group
		OptionGroup* matchOpts = createGroup("Options controlling matching of packages");
		match_invert = matchOpts->add<BoolOption>("invert", 'i', "invert", "",
				"invert the match, selecting non-matching items");

		cat = addEngine("cat", "", "output the full package tag database");
		cat->add(matchOpts);
		cat->add(collOutputOpts);

        check = addEngine("check", "<file>", 
            "check that all the tags in the given tagged collection are present "
            "in the tag vocabulary.  Checks the main database if no file is "
            "specified");

        diff = addEngine("diff", "[filename]",
            "create a tag patch between the current tag database and the tag"
            " collection [filename].  Standard input is used if filename is not specified");
        diff->aliases.push_back("mkpatch");

        dumpavail = addEngine("dumpavail", "[tag expression]",
            "output the full package database");
        dumpavail->add(matchOpts);
        dumpavail->add(pkgOutputOpts);

        grep = addEngine("grep", "<tag expression>",
            "output the lines of the full package tag database that match"
            " the given tag expression. A tag expression (given as a single"
            " argument) is an arbitrarily complex binary expression of tag"
            " names. For example: role::program && ((use::editing || use::viewing)"
            " && !works-with::text)");
        grep->add(matchOpts);
        grep->add(collOutputOpts);

        search = addEngine("search", "<tag expression>",
            "output the names and descriptions of the packages that match"
            " the given tag expression");
        search->add(matchOpts);
        search->add(pkgOutputOpts);

        show = addEngine("show", "<pkg>",
            "show informations about a package, like apt-cache show does, but "
            "adding the tag informations from the debtags index");

        submit = addEngine("submit", "[patch]",
            "upload the given patch file to the central tag repository."
            " If [patch] is omitted, mail the local tag modifications"
            " (uses debtags-submit-patch)");

        tag = addEngine("tag", "{add|rm|ls} <package> [tags...]",
            "view and edit the tags for a package",
            "General manipulation of tags, useful for automation in scripts.\n"
            "It can be used in three ways:\n"
            "tag add <package> <tags...> will add the tags to the given package\n"
            "tag rm <package> <tags...> will remove the tags from the given package\n"
            "tag ls <package> will output the names of the tags of the given package");

        tagcat = addEngine("tagcat", "", "output the tag vocabulary");

        tagshow = addEngine("tagshow", "", 
            "show the vocabulary informations about a tag");

        tagsearch = addEngine("tagsearch", "<string [string [string ...]]>",
            "show a summary of all tags whose data contains the given strings");

        // Create the collection update group
        OptionGroup* updateOpts = createGroup("");
        misc_local = updateOpts->add<BoolOption>("local", 0, "local", "",
                "do not download files when performing an update");
        misc_reindex = updateOpts->add<BoolOption>("reindex", 0, "reindex",
                "", "do not download any file, just do reindexing if needed");
        update = addEngine("update", "",
                "updates the package tag database (requires root)",
                "Collect package tag data from the sources listed in "
                "/etc/debtags/sources.list, then regenerate the debtags "
                "tag database and main index.\n"
                "It needs to be run as root");
        update->add(updateOpts);

        // Create the collection vocfilter group
        OptionGroup* vocfilterOpts = createGroup("");
        misc_vocfile = vocfilterOpts->add<StringOption>("vocabulary", 0,
                "vocabulary", "file",
                "vocabulary file to use instead of the current debtags vocabulary");
        vocfilter = addEngine("vocfilter", "tagfile", 
                "filter out the tags that are not found in the given vocabulary file");
        vocfilter->add(vocfilterOpts);
    }
};

// vim:set ts=4 sw=4:
#endif
