/* sec: convert time string to seconds since the epoch
   see also: seconds(1) */
#include <u.h>
#include <libc.h>

enum {
	Tyear = 0,
	Tmon,
	Tday,
	Thour,
	Tmin,
	Tsec,
	Tsize,
	Tnone,
};

int timearg[Tsize];
int vflg;

void
usage(void)
{
	fprint(2, "usage: %s [-v] [yyyy[mm[dd[HH[MM[SS]]]]]]\n", argv0);
	fprint(2, "       %s -m[v] [mm[dd[HH[MM[SS]]]]]\n", argv0);
	fprint(2, "       %s -d[v] [dd[HH[MM[SS]]]]\n", argv0);
	fprint(2, "       %s -h[v] [HH[MM[SS]]]\n", argv0);
	exits("usage");
}

int
isdigit(char c)
{
	return (c >= '0' && c <= '9');
}

int
readint(char *s, int len, int *to, int *read)
{
	*to = 0;
	*read = 0;

	while(*s != '\0' && len > 0) {
		if(isdigit(*s)) {
			*to = 10 * *to + *s - '0';
			len--;
		}
		s++;
		*read += 1;
	}
	while(*s != '\0' && !isdigit(*s)) {
		s++;
		*read += 1;
	}
	return (len == 0);
}

void
lastmonth(Tm *tm)
{
	if(tm->mon == 0) {
		tm->year--;
		tm->mon = 11;
	} else
		tm->mon--;
}

void
yesterday(Tm *tm)
{
	long sec;

	sec = tm2sec(tm);
	sec -= 86400;
	localtime(sec);
}

int
isfuture(Tm *tm, Tm *now)
{
	if(tm->mon > now->mon)
		return 1;
	if(tm->mon == now->mon) {
		if(tm->mday > now->mday)
			return 1;
		if(tm->mday == now->mday) {
			if(tm->hour > now->hour)
				return 1;
			if(tm->hour == now->hour) {
				if(tm->min > now->min)
					return 1;
			}
		}
	}
	return 0;
}

void
main(int argc, char *argv[])
{
	int start, n, i;
	Tm *tm, now;
	char *p;
	long sec;

	start = Tyear;

	ARGBEGIN {
	case 'm':
		start = Tmon;
		break;
	case 'd':
		start = Tday;
		break;
	case 'h':
		start = Thour;
		break;
	case 'v':
		vflg = 1;
		break;
	default:
		usage();
	} ARGEND

	switch(argc) {
	case 0:
		if(start == Tyear)
			start = Tnone;
		else
			start++;
		break;
	case 1:
		p = argv[0];
		i = start;
		while(*p != '\0' && i < Tsize) {
			if(!readint(p, i == Tyear ? 4 : 2, &timearg[i], &n))
				usage();
			p += n;
			i++;
		}
		break;
	default:
		usage();
	}

	tm = localtime(time(0));
	now = *tm;

	for(i = start; i < Tsize; i++) {
		n = timearg[i];
		switch(i) {
		case Tyear:
			tm->year = n - 1900;
			break;
		case Tmon:
			if(n < 0 || n > 12)
				usage();
			if(n == 0)
				n = 1;
			tm->mon = n - 1;
			break;
		case Tday:
			if(n < 0 || n > 31)
				usage();
			if(n == 0)
				n = 1;
			tm->mday = n;
			break;
		case Thour:
			if(n < 0 || n > 23)
				usage();
			tm->hour = n;
			break;
		case Tmin:
			if(n < 0 || n > 59)
				usage();
			tm->min = n;
			break;
		case Tsec:
			if(n < 0 || n > 59)
				usage();
			tm->sec = n;
		}
	}

	if(start >= Tmon && start <= Thour && isfuture(tm, &now)) {
		switch(start) {
		case Tmon:
			tm->year--;
			break;
		case Tday:
			lastmonth(tm);
			break;
		case Thour:
			yesterday(tm);
		}
	}

	sec = tm2sec(tm);
	print("%d\n", sec);

	if(vflg) {
		fprint(2, "%04d-%02d-%02d %02d:%02d:%02d\n",
			timearg[Tyear], timearg[Tmon], timearg[Tday],
			timearg[Thour], timearg[Tmin], timearg[Tsec]);
		fprint(2, "%s", asctime(localtime(sec)));
	}

	exits(0);
}
