/*
 * main.c for tesh NT
 * $Id: main.c,v 1.19 2004/06/16 08:21:52 tesh Exp $
 * 010710 cj,cb
 *
 * (C) 2001 Christian Jacobi
 * (C) 2001 Christoph Berg
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <time.h>
#include <ncurses.h>

#include "teshline.h"
#include "assert.h"
#include "crypt.h"
#include "db.h"
#include "help.h"
#include "log.h"

#define TESH_RELEASE "NT2.0"
#define MIN_PW_LEN 4
#define TOK_SEP " "

void buchungen(struct db_kunde *kunde) {
	if(!check_tante_pw(kunde)) {
		printf("  Passwort falsch. Keine Auskunft moeglich.\n");
		return;
	}

	print_letzte_zahlungen(kunde);
}

void info(struct db_kunde *kunde) {
	if(!check_tante_pw(kunde)) {
		printf("  Passwort falsch. Keine Auskunft moeglich.\n");
		return;
	}

	printf("  Login:           %s (ID %u)\n", kunde->nickname, kunde->kid);
	printf("  Name:            %s %s\n", kunde->vorname, kunde->nachname);
	printf("  Email:           %s\n", kunde->email);
	printf("  Passwort:        %s\n", kunde->pw);
	printf("  Guthaben:        %s EUR %s\n",
			betrag2s(kunde->guthaben),
			kunde->guthaben<0 ? "SOLL\7" : "");
	printf("  Kunde seit:      %s\n", tante_strftime(kunde->created));
	printf("  Letzter Einkauf: %s\n", tante_strftime(kunde->last_contact));
	if(kunde->locked) {
		printf("  ACCOUNT GESPERRT\n");
	}
	print_zahlungen(kunde);
}

void passwd(struct db_kunde *kunde) {
	char *pw1, *pw2, *cryptpw;

	if(!check_tante_pw(kunde)) {
		printf("  Passwort falsch. Passwort kann nicht geaendert werden.\n");
		return;
	}

	pw1 = static_strdup(getpass("  Neues Passwort: "));
	if(strlen(pw1) < MIN_PW_LEN) {
		printf("  Das Passwort muß mindestens %u Zeichen haben!%c\n", MIN_PW_LEN, '\007');
		return;
	}

	pw2 = getpass(       "  Wiederholen:    ");
	if(strcmp(pw1, pw2)) {
		printf("  Passwoerter sind verschieden. Passwort nicht geaendert.%c\n", '\007');
		return;
	}

	cryptpw = crypt(pw1, cryptseed());
	set_passwd(kunde, cryptpw);
	printf("  Passwort geaendert.\n");
}

void ueberweisung(struct db_kunde *kunde) {
	struct db_kunde kunde1;
	struct db_kunde *kunde2;
	char *line;
	int betrag;

	kunde1 = *kunde; // copy static data

	line = get_tante_str("  Ueberweisen an: ");
	assert(line != NULL);
	clipstr(line);
	if((kunde2 = get_kunde_by_nickname(line)) == NULL) {
		printf("  Benutzer '%s' unbekannt!\n", line);
		return;
	}
	if(kunde1.kid == kunde2->kid) {
		printf("  Du kannst dir selbst nichts ueberweisen!\n");
		return;
	}
	printf("  Ueberweisung an %s (%s %s)\n", kunde2->nickname,
			kunde2->vorname, kunde2->nachname);

	line = get_tante_str("  Betrag in EUR: ");
	assert(line != NULL);
	betrag = (int)(atof(clipstr(komma(line))) * 100.0);
	if(betrag == 0) {
		printf("  Anscheinend willst du nichts ueberweisen.\n");
		return;
	}
	if(betrag < 0) {
		printf("  Wer will denn hier anderen Leuten Geld abziehen??.\n");
		writelog(L_ERROR, "%s (%d) moechte einen negativen Betrag (%d) "
				"an %s (%d) ueberweisen\n",
				kunde1.nickname, kunde1.kid, betrag,
				kunde2->nickname, kunde2->kid);
		return;
	}
	printf("  Betrag: %18s EUR\n", betrag2s(betrag));
	
	line = get_tante_str("  Betreff: ");
	assert(line != NULL);
	if(*line == '\0') {
		printf("  Kein Betreff, Ueberweisung abgebrochen.\n");
		return;
	}

	if(!check_tante_pw(&kunde1)) {
		printf("  Passwort falsch. Ueberweisung nicht moeglich.\n");
		return;
	}

	print_zahlungen(&kunde1);

	printf("  Altes Guthaben: %18s EUR\n", betrag2s(kunde1.guthaben));
	db_ueberweisung(&kunde1, kunde2, betrag, line);
	printf("  Neues Guthaben: %18s EUR\n",
			betrag2s(kunde1.guthaben));
	if (kunde1.guthaben<0)
		printf("Es waere nett, wenn du mal wieder bezahlen wuerdest!\7\n");
}

void einkaufen(char *line, char *line2, char *token, struct db_kunde *kunde) {
	struct db_artikel *artikel;
	int zahl;
	float gesamt;

	zahl = 0;
	gesamt = 0.0;
	for(; token != NULL; token=strtok(NULL, TOK_SEP)) {
		if((artikel = get_artikel_by_name(token)) == NULL) {
			printf("  '%s' gibt es nicht!\n", token);
		} else {
			printf("  Einkauf: %-20s %s EUR\n",
					artikel->name,
					betrag2s(artikel->preis));
			zahl++;
			gesamt += artikel->preis;
		}
	}
	if(zahl > 1) {
		printf("  Gesamt: %26s EUR\n", betrag2s(gesamt));
	}
	if(!check_tante_pw(kunde)) {
		printf("  Passwort falsch, kein Einkauf moeglich!%c\n", '\007');
		return;
	}

	print_zahlungen(kunde);
	printf("  Altes Guthaben: %18s EUR\n",
			betrag2s(kunde->guthaben));
	token = strtok(line2, TOK_SEP); // munch line again, skip kundenname
	for(token = strtok(NULL, TOK_SEP); token != NULL; token=strtok(NULL, TOK_SEP)) {
		if((artikel = get_artikel_by_name(token)) != NULL) {
			artikel_einkauf(kunde, artikel, artikel->name);
			// printf("  %s gekauft.\n", artikel->name);
		}
	}
	printf("  Neues Guthaben: %18s EUR\n",
			betrag2s(kunde->guthaben));
	if (kunde->guthaben<0)
		printf("Es waere nett, wenn du mal wieder bezahlen wuerdest!\7\n");
}

void tante_loop() {
	char *line, *line2;
	char *token, *token2;
	struct db_kunde *kunde;

	line = get_tante_str(PROMPT);
	assert(line != NULL); // exit abnormally
	line2 = static_strdup(line); // save line for 2nd strtok run

	token = strtok(line, TOK_SEP);
	if(token == NULL) {
		return;
	}

	if(!strcmp(token, "exit") && check_super_pw()) {
		exit(0);
	}

	if(!strcmp(token, "help") || !strcmp(token, "hilfe")) {
		help();
		return;
	}

	// "rumgedrehte" Befehle ---
	if(!strcmp(token, "buchungen") || !strcmp(token, "info") ||
	   !strcmp(token, "passwd") || !strcmp(token, "ueberweisung")) {
		token2=strtok(NULL, TOK_SEP);
		if(token2 == NULL) {
			printf("  Kein Benutzername angegeben!\n");
			return;
		}
		if((kunde = get_kunde_by_nickname(token2)) == NULL) {
			printf("  Benutzer '%s' unbekannt!\n", token2);
			return;
		}
		if(!strcmp(token, "buchungen")) buchungen(kunde);
		if(!strcmp(token, "info")) info(kunde);
		if(!strcmp(token, "passwd")) passwd(kunde);
		if(!strcmp(token, "ueberweisung")) ueberweisung(kunde);
		return;
	}
	// -------------------------

	if((kunde = get_kunde_by_nickname(token)) == NULL) {
		printf("  Benutzer '%s' unbekannt!\n", token);
		return;
	}

	token=strtok(NULL, TOK_SEP);
	if(token == NULL) {
		printf("  Hmm, anscheinend willst du nichts kaufen.\n");
		return;
	}

	if(!strcmp(token, "buchungen")) { // buchungen wird "eingekauft"
		buchungen(kunde);
		return;
	}
	if(!strcmp(token, "info")) { // info wird "eingekauft"
		info(kunde);
		return;
	}
	if(!strcmp(token, "passwd")) {
		passwd(kunde);
		return;
	}
	if(!strcmp(token, "ueberweisung")) {
		ueberweisung(kunde);
		return;
	}

	einkaufen(line, line2, token, kunde);
	return;
}


int main(int argc, char **argv) {
	argv_0 = argv[0]; // global pointer (used in log.c)

	writelog(L_LOG, "TESH started (" TESH_RELEASE " " __DATE__ " " __TIME__ ")\n");
	printf("%c[2J\nThis is tesh. (" TESH_RELEASE " " __DATE__ " " __TIME__ ")\n", 0x1b);

	init_signals();
	init_db();
	init_readline();

	help();

	for(;;) {
		tante_loop();
	}

	return 0;
}
