/*
 * Copyright (C) 2016 Sami Kerola <kerolasa@iki.fi>
 * Copyright (C) 2016 Karel Zak <kzak@redhat.com>
 *
 * Copyright (c) 1980, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
 *	added Native Language Support
 * 1999-09-19 Bruno Haible <haible@clisp.cons.org>
 *	modified to work correctly in multi-byte locales
 */

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#include "nls.h"
#include "c.h"
#include "widechar.h"
#include "closestream.h"

/*
 * colcrt - replaces col for crts with new nroff esp. when using tbl.
 * Bill Joy UCB July 14, 1977
 *
 * This filter uses the up and down sequences generated by the new
 * nroff when used with tbl and by \u \d and \r.
 * General overstriking doesn't work correctly.
 * Underlining is split onto multiple lines, etc.
 *
 * Option - suppresses all underlining.
 * Option -2 forces printing of all half lines.
 */

enum { OUTPUT_COLS = 132 };

struct colcrt_control {
	FILE		*f;
	wchar_t		line[OUTPUT_COLS + 1];
	wchar_t		line_under[OUTPUT_COLS + 1];
	unsigned int	print_nl:1,
			need_line_under:1,
			no_underlining:1,
			half_lines:1;
};

static void __attribute__((__noreturn__)) usage(FILE *out)
{
	fputs(USAGE_HEADER, out);
	fprintf(out, _(" %s [options] [<file>...]\n"), program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Filter nroff output for CRT previewing.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -,  --no-underlining    suppress all underlining\n"), out);
	fputs(_(" -2, --half-lines        print all half-lines\n"), out);

	fputs(USAGE_SEPARATOR, out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);

	fprintf(out, USAGE_MAN_TAIL("colcrt(1)"));

	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}

static void trim_trailing_spaces(wchar_t *s)
{
	size_t size;
	wchar_t *end;

	size = wcslen(s);
	if (!size)
		return;
	end = s + size - 1;
	while (s <= end && iswspace(*end))
		end--;
	*(end + 1) = L'\0';
}


static void output_lines(struct colcrt_control *ctl, int col)
{
	/* first line */
	trim_trailing_spaces(ctl->line);
	fputws(ctl->line, stdout);

	if (ctl->print_nl)
		fputwc(L'\n', stdout);
	if (!ctl->half_lines && !ctl->no_underlining)
		ctl->print_nl = 0;

	wmemset(ctl->line, L'\0', OUTPUT_COLS);

	/* second line */
	if (ctl->need_line_under) {
		ctl->need_line_under = 0;
		ctl->line_under[col] = L'\0';
		trim_trailing_spaces(ctl->line_under);
		fputws(ctl->line_under, stdout);
		fputwc(L'\n', stdout);
		wmemset(ctl->line_under, L' ', OUTPUT_COLS);

	} else if (ctl->half_lines && 0 < col)
		fputwc(L'\n', stdout);
}

static int rubchars(struct colcrt_control *ctl, int col, int n)
{
	while (0 < n && 0 < col) {
		ctl->line[col] = L'\0';
		ctl->line_under[col] = L' ';
		n--;
		col--;
	}
	return col;
}

static void colcrt(struct colcrt_control *ctl)
{
	int col;
	wint_t c;
	long old_pos;

	ctl->print_nl = 1;
	if (ctl->half_lines)
		fputwc(L'\n', stdout);

	for (col = 0; /* nothing */; col++) {
		if (OUTPUT_COLS - 1 < col) {
			output_lines(ctl, col);
			errno = 0;
			old_pos = ftell(ctl->f);
			while ((c = getwc(ctl->f)) != L'\n') {
				long new_pos = ftell(ctl->f);
				if (old_pos == new_pos)
					fseek(ctl->f, 1, SEEK_CUR);
				else
					old_pos = new_pos;
				if (errno == 0 && c == WEOF)
					return;
				else
					errno = 0;
			}
			col = -1;
			continue;
		}
		c = getwc(ctl->f);
		switch (c) {
		case 033:	/* ESC */
			c = getwc(ctl->f);
			if (c == L'8') {
				col = rubchars(ctl, col, 1);
				continue;
			}
			if (c == L'7') {
				col = rubchars(ctl, col, 2);
				continue;
			}
			continue;
		case WEOF:
			ctl->print_nl = 0;
			output_lines(ctl, col);
			return;
		case L'\n':
			output_lines(ctl, col);
			col = -1;
			continue;
		case L'\t':
			for (/* nothing */; col % 8 && col < OUTPUT_COLS; col++) {
				ctl->line[col] = L' ';
			}
			col--;
			continue;
		case L'_':
			ctl->line[col] = L' ';
			if (!ctl->no_underlining) {
				ctl->need_line_under = 1;
				ctl->line_under[col] = L'-';
			}
			continue;
		default:
			if (!iswprint(c)) {
				col--;
				continue;
			}
			ctl->print_nl = 1;
			ctl->line[col] = c;
		}
	}
}

int main(int argc, char **argv)
{
	struct colcrt_control ctl = { NULL };
	int opt;
	enum { NO_UL_OPTION = CHAR_MAX + 1 };

	static const struct option longopts[] = {
		{"no-underlining", no_argument, NULL, NO_UL_OPTION},
		{"half-lines", no_argument, NULL, '2'},
		{"version", no_argument, NULL, 'V'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	/* Take care of lonely hyphen option. */
	for (opt = 0; opt < argc; opt++) {
		if (argv[opt][0] == '-' && argv[opt][1] == '\0') {
			ctl.no_underlining = 1;
			argc--;
			memmove(argv + opt, argv + opt + 1,
				sizeof(char *) * (argc - opt));
			opt--;
		}
	}

	while ((opt = getopt_long(argc, argv, "2Vh", longopts, NULL)) != -1) {
		switch (opt) {
		case NO_UL_OPTION:
			ctl.no_underlining = 1;
			break;
		case '2':
			ctl.half_lines = 1;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	argc -= optind;
	argv += optind;

	do {
		wmemset(ctl.line, L'\0', OUTPUT_COLS);
		wmemset(ctl.line_under, L' ', OUTPUT_COLS);

		if (argc > 0) {
			if (!(ctl.f = fopen(*argv, "r")))
				err(EXIT_FAILURE, _("cannot open %s"), *argv);
			argc--;
			argv++;
		} else
			ctl.f = stdin;

		colcrt(&ctl);
		if (ctl.f != stdin)
			fclose(ctl.f);
	} while (argc > 0);

	return EXIT_SUCCESS;
}
