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

#define DEFAULT_TAB_LENGTH 8

int is_str_uint(char *str);
int is_tab_stop_arg_list_valid(int argc, char *argv[]);

int main(int argc, char *argv[])
{
    if (!is_tab_stop_arg_list_valid(argc, argv))
    {
        puts("Error: invalid tab stop list.\n");
        return EXIT_FAILURE;
    }

    int c;
    size_t arg_pos = 1;
    size_t line_pos = 0;
    size_t tab_stop = DEFAULT_TAB_LENGTH;
    size_t nr_of_spaces;
    size_t nr_of_custom_tab_stops = argc - 1;

    while ((c = getchar()) != EOF)
    {
        if (c == '\t')
        {
            if (nr_of_custom_tab_stops)
            {
                tab_stop = atoi(argv[arg_pos++]);
                --nr_of_custom_tab_stops;
            }
            else if (argc > 1)
            {
                tab_stop = 1;
            }

            nr_of_spaces = tab_stop - line_pos % tab_stop;

            while (nr_of_spaces)
            {
                putchar(' ');
                ++line_pos;
                --nr_of_spaces;
            }
        }
        else
        {
            putchar(c);
            ++line_pos;

            if (c == '\n')
            {
                arg_pos = 1;
                line_pos = 0;
                nr_of_custom_tab_stops = argc - 1;
            }
        }
    }

    return EXIT_SUCCESS;
}

int is_str_uint(char *str)
{
    for (size_t i = 0; i < strlen(str); ++i)
    {
        if (!isdigit(str[i]))
        {
            return 0;
        }
    }
    return 1;
}

int is_tab_stop_arg_list_valid(int argc, char *argv[])
{
    for (size_t i = 1; i < argc; ++i)
    {
        if (!is_str_uint(argv[i]) || (i > 1 && atoi(argv[i - 1]) > atoi(argv[i])))
        {
            return 0;
        }
    }
    return 1;
}

// NOTE: The current program works in a similar fashion as expand.
// run: ./detab 4 8 12 16 < file_tabs.txt > file_spaces.txt
