/* cli.c - Implementasi parsing argumen */
#include "cli.h"

#include <string.h>
#include <stdlib.h>

#define PROGRAM_NAME "mtool"
#define PROGRAM_VERSION "1.0.0"

void cli_print_help(FILE *out) {
    fprintf(out,
        "Penggunaan: %s [SUBCOMMAND] [OPTION]... [FILE]\n"
        "\n"
        "Alat pemrosesan teks baris perintah sederhana.\n"
        "\n"
        "Subperintah:\n"
        "  (none)             Baca stdin dan cetak jumlah baris.\n"
        "  help               Tampilkan pesan ini.\n"
        "  version            Tampilkan versi program.\n"
        "  count [FILE]       Hitung jumlah baris di FILE (atau stdin).\n"
        "  head [-n N] [FILE] Cetak N baris pertama (default 10).\n"
        "  tail [-n N] [FILE] Cetak N baris terakhir (default 10).\n"
        "  stats [FILE]       Statistik: jumlah baris, kata, karakter.\n"
        "  grep PATTERN [-i] [FILE]\n"
        "                     Cetak baris yang mengandung PATTERN.\n"
        "\n"
        "Opsi:\n"
        "  -n N               Jumlah baris untuk head/tail.\n"
        "  -i                 Case-insensitive untuk grep.\n"
        "  -v                 Verbose log ke stderr.\n"
        "  --help             Tampilkan pesan bantuan.\n"
        "  --version          Tampilkan versi.\n",
        PROGRAM_NAME);
}

void cli_print_version(FILE *out) {
    fprintf(out, "%s %s\n", PROGRAM_NAME, PROGRAM_VERSION);
}

/* Cek apakah string diawali tanda strip (option). */
static int is_option(const char *s) {
    return s != NULL && s[0] == '-' && s[1] != '\0';
}

int cli_parse(int argc, char *argv[], cli_args *out) {
    if (out == NULL) {
        return -1;
    }
    memset(out, 0, sizeof(*out));
    out->count = 10; /* default untuk head/tail */

    if (argc < 2) {
        out->subcommand = CLI_SUB_COUNT;
        return 0;
    }

    int i = 1;
    /* Deteksi subperintah pertama bila bukan option. */
    if (!is_option(argv[i])) {
        const char *cmd = argv[i];
        if (strcmp(cmd, "help") == 0 || strcmp(cmd, "--help") == 0) {
            out->subcommand = CLI_SUB_HELP;
            out->show_help = 1;
            return 0;
        }
        if (strcmp(cmd, "version") == 0 || strcmp(cmd, "--version") == 0) {
            out->subcommand = CLI_SUB_VERSION;
            out->show_version = 1;
            return 0;
        }
        if (strcmp(cmd, "count") == 0) {
            out->subcommand = CLI_SUB_COUNT;
        } else if (strcmp(cmd, "head") == 0) {
            out->subcommand = CLI_SUB_HEAD;
        } else if (strcmp(cmd, "tail") == 0) {
            out->subcommand = CLI_SUB_TAIL;
        } else if (strcmp(cmd, "stats") == 0) {
            out->subcommand = CLI_SUB_STATS;
        } else if (strcmp(cmd, "grep") == 0) {
            out->subcommand = CLI_SUB_GREP;
        } else if (cmd[0] == '-' && cmd[1] == '-') {
            /* long option tanpa subcommand */
            out->subcommand = CLI_SUB_COUNT;
        } else if (is_option(cmd)) {
            /* short option tanpa subcommand: anggap count */
            out->subcommand = CLI_SUB_COUNT;
        } else {
            /* Bukan subperintah yang dikenal, anggap sebagai path file. */
            out->subcommand = CLI_SUB_COUNT;
            out->file_path = cmd;
            i++;
            return 0;
        }
        i++;
    } else {
        out->subcommand = CLI_SUB_COUNT;
    }

    /* Khusus grep: argumen non-option pertama adalah PATTERN. */
    if (out->subcommand == CLI_SUB_GREP) {
        if (i >= argc) {
            return -1; /* grep butuh pattern */
        }
        out->pattern = argv[i++];
    }

    /* Iterasi sisa argumen. */
    while (i < argc) {
        const char *a = argv[i];
        if (strcmp(a, "-n") == 0) {
            if (i + 1 >= argc) {
                return -1;
            }
            out->count = (int)strtol(argv[++i], NULL, 10);
            if (out->count < 0) {
                return -1;
            }
            i++;
        } else if (strcmp(a, "-i") == 0) {
            out->ignore_case = 1;
            i++;
        } else if (strcmp(a, "-v") == 0) {
            out->verbose = 1;
            i++;
        } else if (strcmp(a, "--help") == 0) {
            out->show_help = 1;
            i++;
        } else if (strcmp(a, "--version") == 0) {
            out->show_version = 1;
            i++;
        } else if (is_option(a)) {
            return -1; /* option tidak dikenal */
        } else {
            /* Argumen non-option: file_path. */
            if (out->file_path == NULL) {
                out->file_path = a;
            } else {
                return -1; /* lebih dari satu file (tidak didukung) */
            }
            i++;
        }
    }
    return 0;
}
