#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <limits.h>
#include "../lpi.h"

int
main(int argc, char *argv[])
{
    unsigned long long orignumber, number;
    int curopt, bit, c, nflag;
    char *v[2] = {NULL, NULL};
    char *str, *bits;

    struct option lopts[] = {
        {"on", optional_argument, NULL, 0},
        {"off", optional_argument, NULL, 0},
        {NULL, 0, NULL, 0}
    };

    /* don't show input number by default. */
    nflag = 0;
    while ((c = getopt_long(argc, argv, "n", lopts, &curopt)) != -1) {
        switch (c) {
        case 0:
            if (strcmp(lopts[curopt].name, "off") == 0)
                v[0] = optarg;
            else if (strcmp(lopts[curopt].name, "on") == 0)
                v[1] = optarg;
            break;

        case 'n':
            nflag = 1;  /* show input number */
            break;

        default:
            warnx("unknown option");
            break;
        }
    }

    if (v[0] && v[1])
        errx(EXIT_FAILURE, "just one option allowed. --on and --off?");

    if (optind >= argc)
        number = v[0] ? number = ULLONG_MAX : 0;
    else
        if ((errno = toLongLong(argv[optind], &number)) != 0)
            err(EXIT_FAILURE, "toLongLong('%s')", argv[optind]);

    orignumber = number;
    for (int i = 0; i < 2; i++) {
        if ((bits = v[i]) == NULL)
            continue;

        while ((str = strtok(bits, ",")) != NULL) {
            bits = NULL;
            if ((errno = toInt(str, &bit)) != 0) {
                warn("toInt('%s')", str);
                continue;
            }
            if (bit < 1 || bit > 64)
                errx(EXIT_FAILURE, "invalid bit number %d", bit);
            onOffBits(&number, bit - 1, i);
        }
    }

    if (nflag)
        printf("number %s\n", toBase(orignumber, 2, 64, 4, ' '));

    printf("%s%s\n", nflag ? "       " : "", toBase(number, 2, 64, 4, ' '));
    exit(EXIT_SUCCESS);
}

