#!/usr/bin/env python3
import hra.db as db
import hra.lib as lib
from hra.util import hash_passwd
import time
from datetime import datetime

import argparse
from sqlalchemy import exc, update
import sys


parser = argparse.ArgumentParser()
parser.add_argument("game_id")
parser.add_argument("--step", action="store_true")
parser.add_argument("--born-per-round", nargs="+", type=int)
parser.add_argument("--restore", action="store_true")
parser.add_argument("--set-step-mode", type=str)
parser.add_argument("--set-step-s", type=int)
parser.add_argument("--autosteps", action="store_true", help="Bude periodicky posouvat hru podle konfigurace")

args = parser.parse_args()

ses = db.get_session()

game_id = args.game_id
game = ses.query(db.Game).filter_by(game_id=game_id).one_or_none()


if args.autosteps:
    while True:
        def sleep(timeout=1):
            ses.commit()
            timeout = max(0.1, timeout)
            print(f"Waiting {float(timeout):.2f}")
            time.sleep(timeout)

        ses.expire_all()
        game = ses.query(db.Game).filter_by(game_id=game_id).one_or_none()
        assert game is not None
        state = game.current_state()
        if not state:
            print("There is no state now")
            sleep(1)
            continue
        if game.step_mode != db.StepMode.automatic:
            print(f"Step mode {game.step_mode} is not automatic")
            sleep(1)
            continue
        step_every_s = game.step_every_s
        t = datetime.now()
        diff = (t - state.create_time).total_seconds()
        if diff >= step_every_s:
            print("Doing step")
            lib.game_step(game_id)
            print("Done")
            t_new = datetime.now()
            diff = (t_new - t).total_seconds()
            step_in = game.step_every_s - diff
            sleep(step_in)
        else:
            step_in = game.step_every_s - diff
            print(f"Step in {step_in:.2f} s (every {game.step_every_s})")
            sleep(step_in)
else:
    game.lock()
    if args.born_per_round:
        print(args.born_per_round)
        c = game.get_configuration()
        c["born_per_round"] = args.born_per_round
        game.configuration = db.new_big_data(c)
        ses.commit()
        print(game.get_configuration())
    if args.set_step_mode:
        game.step_mode = db.StepMode(args.set_step_mode)
        ses.commit()
    if args.set_step_s:
        game.step_every_s = args.set_step_s
        ses.commit()
    if args.restore:
        lib.game_restore_broken(args.game_id)
    if args.step:
        lib.game_step(args.game_id)