#include <stdio.h>

#define NOFILE_ERR	1
#define	ARG_ERR		2
#define TABLE_ERR	3


int main(int argc, char **argv)
{
	char map[26]; /* With file/argument length checking, this doesn't need to be defaulted to anything. */
	int current;

	if(argc == 1)
	{
		/* Print usage */

		fprintf(stderr, "\tsyntax: %s ( <FILENAME> | -i <TABLE> )\n", argv[0]);
		fprintf(stderr,	"FILENAME:  Name of a file containing the translation table to be used.\n");
		fprintf(stderr, "TABLE:  Immediate translation table.\n");
		fprintf(stderr, "Table *must* be 26 characters long and *should* contain 26 unique letters.");

		exit(ARG_ERR);
	}

	if(argc == 2)
	{

		/* open file named in argv[1]
		 * read 26 chars into translation buffer
		 */

		FILE *trans;

		if(trans = fopen(argv[1], "r"))
		{
			int letter;

			for(letter = 0; letter < 26; ++letter)
			{
				if((map[letter] = fgetc(trans)) == EOF)
				{
					fprintf(stderr, "Incomplete translation file!");
					exit(TABLE_ERR);
				}
			}

			letter = fgetc(trans);

			(void) fclose(trans);

			if(letter != EOF)
			{
				fprintf(stderr, "Extra characters in translation file!");
					exit(TABLE_ERR);
			}
		}
		else
		{
			fprintf(stderr, "Unable to open file %s.", argv[1]);
			exit(NOFILE_ERR);
		}
	}

	if(argc == 3)
	{
		/* read translation table from the command line
		 */

		int letter;

		if(strcmp("-i", argv[1]) != 0)
		{
			fprintf(stderr, "\"-i\" is the only supported option.");
			exit(ARG_ERR);
		}


		if((letter = strlen(argv[2])) != 26)
		{
			fprintf(stderr, "Translation table must be 26 characters long! Found: %d.", letter);
			exit(TABLE_ERR);
		}

		for(letter = 0; letter < 26; ++letter)
		{
			map[letter] = argv[2][letter];
		}
	}

	if(argc > 3)
	{
		fprintf(stderr, "Too many arguments.");
		exit(ARG_ERR);
	}


	/* Done processing arguments.
	 * For each character of standard input, if it is a letter,
	 * print the corresponding character from the translation table.
	 * Otherwise, echo the character straight through to stdout.
	 */

	while((current = fgetc(stdin)) != EOF)
	{
		int lower = current | 0x20;

		if(lower >= 'a' && lower <= 'z')
		{
			fprintf(stdout, "%c", map[lower - 'a']);
		}
		else
		{
			fprintf(stdout, "%c", current);
		}

		(void) fflush(stdout);
	}

	exit(0);
}
