#include "main.h"

static
int
lsa_main(
    int argc,
    char* argv[]
    );

static
main_entry*
find_entry(
    const char* name
    );

static
int
deprecated_find_main(
    int argc,
    char* argv[]
    )
{
    fprintf(stderr, "This command is deprecated; use lw-lsa find-objects\n");

    exit(1);
}

static
int
deprecated_enum_main(
    int argc,
    char* argv[]
    )
{
    fprintf(stderr, "This command is deprecated; use lw-lsa enum-objects\n");
    exit(1);
}

static
int
deprecated_member_main(
    int argc,
    char* argv[]
    )
{
    fprintf(stderr, "This command is deprecated; use lw-lsa query-member-of\n");
    exit(1);
}

static main_entry entry_list[] =
{
    {"ad-cache", ad_cache_main, "Manipulate AD provider cache"},
    {"ad-get-machine", ad_get_machine_main, "Get AD machine account information"},
    {"ad-reload-join-state", ad_reload_join_state_main, "Reload AD provider join information"},
    {"get-status", get_status_main, "Show status of all providers"},
    {"add-group", add_group_main, "Add group to local account database"},
    {"add-user", add_user_main, "Add user to local account database"},
    {"del-group", del_group_main, "Delete group from local account database"},
    {"del-user", del_user_main, "Delete user from local account database"},
    {"mod-group", mod_group_main, "Modify local group"},
    {"mod-user", mod_user_main, "Modify local user"},
    {"set-default-domain", set_default_domain_main, "Set default AD domain"},
    {"set-machine-sid", set_machine_sid_main, "Set local machine SID"},
    {"set-machine-name", set_machine_name_main, "Set local machine name"},
    {"find-objects", FindObjectsMain, "Find users and groups"},
    {"enum-objects", EnumObjectsMain, "Enumerate users and groups"},
    {"enum-members", EnumMembersMain, "Enumerate members of a group"},
    {"query-member-of", QueryMemberOfMain, "Get group membership of user or group"},
    {"account-rights", account_rights_main, "Manage account access rights"},
    {"join", JoinMain, "Join an AD domain"},
    {"leave", LeaveMain, "Leave an AD domain"},
    {"-- HIDDEN --", NULL},
    {"get-metrics", get_metrics_main},
    {"trace-info", trace_info_main},
    {"ypcat", lw_ypcat_main},
    {"ypmatch", lw_ypmatch_main},
    {"enum-groups", deprecated_enum_main},
    {"enum-users", deprecated_enum_main},
    {"find-by-sid", deprecated_find_main},
    {"find-group-by-id", deprecated_find_main},
    {"find-group-by-name", deprecated_find_main},
    {"find-user-by-id", deprecated_find_main},
    {"find-user-by-name", deprecated_find_main},
    {"list-groups-for-user", deprecated_member_main},
    {"lsa", lsa_main},
    {NULL, NULL}
};

int main(int argc, char** argv)
{
    main_entry *entry = NULL;
    char* name = basename(argv[0]);

    if (!strncmp(name, "lsa-", 4))
    {
        name += 4;
    }
    else if (!strncmp(name, "lw-", 3))
    {
        name += 3;
    }

    entry = find_entry(name);

    if (!entry)
    {
        fprintf(stderr, "Unrecognized command: %s\n", name);
        return -1;
    }
    else
    {
        return entry->func(argc, argv);
    }
}

static
int
lsa_main(
    int argc,
    char* argv[]
    )
{
    main_entry *entry = NULL;
    int i;
    size_t max_len = 0;
    size_t str_len = 0;

    if (argc < 2 || (argc == 2 &&
        (!strcmp(argv[1], "--help") || !strcmp(argv[1], "--usage"))))
    {
        fprintf(stderr, "Usage: lw-lsa command ...\n\n");
        fprintf(stderr, "Available commands:\n");

        for (i = 0; entry_list[i].func; i++)
        {
            str_len = strlen(entry_list[i].name);
            if (str_len > max_len)
            {
                max_len = str_len;
            }
        }

        for (i = 0; entry_list[i].func; i++)
        {
            str_len = fprintf(stderr, "  %s", entry_list[i].name);
            if (entry_list[i].desc)
            {
                for (;str_len < max_len + 2; str_len++)
                {
                    fprintf(stderr, " ");
                }
                fprintf(stderr, "    %s", entry_list[i].desc);
            }
            fprintf(stderr, "\n");
        }

        return -1;
    }
    entry = find_entry(argv[1]);

    if (!entry)
    {
        fprintf(stderr, "Unrecognized command: %s\n", argv[1]);
        return -1;
    }
    else
    {
        return entry->func(argc - 1, argv + 1);
    }
}

static
main_entry*
find_entry(
    const char* name
    )
{
    int i;

    for (i = 0; entry_list[i].name; i++)
    {
        if (!strcmp(name, entry_list[i].name) && entry_list[i].func)
        {
            return &entry_list[i];
        }
    }

    return NULL;
}
