def main(argv):

    if DEBUG:
        print(f"len(argv): {len(argv)}")

    if len(argv) == 3:
        gameno = argv[1]
        player_name = argv[2]
    else:
        usage()
        sys.exit(1)

    # initialize the data object
    data = GameData(gameno, player_name)

    # load the data 
    while True:

        # load/reload the gamedata
        data.load()

        # set the fields used in the parser
        players = data.getPlayers()
        player_obj = data.getPlayerObj(player_name)
        board = data.getBoard()
        seen_board = data.getSeenBoard()
        size_x = data.getSizeX()
        size_y = data.getSizeY()
        new_game = data.getNewGame()
        unprocessed_moves = data.getUnprocessedMoves()

        # wait 5 seconds if there are unprocessed moves and then reload
        if unprocessed_moves:
            print("waiting for turn to complete...")
            time.sleep(5)
            # restart the loop
            continue

        # interactive mode
        while True:

            # read line from stdin + tokenize it
            print(f"{argv[0]}> ", flush=True, end='')
            line = sys.stdin.readline().rstrip()
            tokens = line.split()

            # ignore empty lines
            if len(tokens) == 0:
                continue

            # command help
            elif tokens[0] == 'help':
                command_help()
                continue

            # show - board, units
            elif tokens[0]=='show':
                if DEBUG:
                    print(f"len(tokens): {len(tokens)}")
                if len(tokens) == 1:
                    print("invalid show command")
                    continue
                elif tokens[1] == 'board':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen board")
                        seen_board.print()
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        board.print(player_obj)

                elif tokens[1] == 'types':
                    for player in players.keys():
                        if 'types' in players[player].keys():    
                            for types in players[player]['types'].keys():
                                for unit_name in players[player]['types'].keys():
                                    unit_type = players[player]['types'][unit_name]
                                    print(f"player: {player}, name: {unit_type['name']}, symbol: {unit_type['symbol']}, attack: {unit_type['attack']}, health: {unit_type['health']}, energy: {unit_type['energy']}")

                elif tokens[1] == 'players':
                    for player in players.keys():
                        print(f"name: {player}, email: {players[player]['email']}")
                elif tokens[1] == 'units':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen units")
                        print(seen_board.listUnits())
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        print(board.listUnits(player_obj))
                else:
                    print("invalid show command")
                    continue

            # add - player, type, unit
            elif tokens[0] == 'add':
                if len(tokens) == 1:
                    print("invalid add command")
                    continue
                elif tokens[1] == 'type':
                    if len(tokens) != 7:
                        print("must provide 5 args for type")
                        continue
                    if new_game == False:
                        print("can't add types after first turn")
                        continue
                    try:
                        type_name = tokens[2]
                        symbol = tokens[3]
                        attack = tokens[4]
                        health = tokens[5]
                        energy = tokens[6]
                        obj = UnitType(type_name, symbol, int(attack), int(health), int(energy))
                        players[player_name]['types'][type_name] = {}
                        players[player_name]['types'][type_name]['name'] = type_name
                        players[player_name]['types'][type_name]['symbol'] = symbol
                        players[player_name]['types'][type_name]['attack'] = attack
                        players[player_name]['types'][type_name]['health'] = health
                        players[player_name]['types'][type_name]['energy'] = energy
                        players[player_name]['types'][type_name]['obj'] = obj
                    except Exception as e:    
                        print(f"error adding unit type: {e}")
                        continue
                elif tokens[1] == 'unit':
                    if len(tokens) != 6:
                        print("must provide 4 args for unit")
                        continue
                    if board == None:
                        print("board must be loaded in order to place units")
                        continue
                    if new_game == False:
                        print("can't add units after first turn")
                        continue
                    try:
                        type_name = tokens[2]
                        name = tokens[3]
                        x = int(tokens[4])
                        y = int(tokens[5])
                        if DEBUG:
                            print(f"{player_obj}, {x}, {y}, {name}, {players[player_name]['types'][type_name]['obj']}")
                        board.add(player_obj, x, y, name, players[player_name]['types'][type_name]['obj'])
                        board.commit()
                    except Exception as e:
                        print(f"error creating new unit {e}")
                        continue
                else:
                    print("invalid add command")
                    continue

            # move - unit
            elif tokens[0] == 'move':
                if len(tokens) != 3:
                    print("must provide 2 args for move")
                    continue
                elif board == None:
                    print("board must be loaded in order to move units")
                    continue
                elif new_game:
                    print("can't move units until after the first turn is complete")
                    continue
                try:
                    unit_name = tokens[1]
                    direction = tokens[2]
                    # TODO - make sure you implment rules to make this unique per player
                    unit = board.getUnitByName(unit_name)[0]
                    if player_name != unit.player.name:
                        print("can't move units belonging to other players")
                        continue
                    if unit.on_board == False:
                        print("can't move units not on the board")
                        continue
                    if direction == 'north':
                        direction = UnitType.NORTH
                    elif direction == 'south':
                        direction = UnitType.SOUTH
                    elif direction == 'east':
                        direction = UnitType.EAST
                    elif direction == 'west':
                        direction = UnitType.WEST
                    else:
                        print(f"invalid direction {direction}")
                        continue
                    unit.move(direction)
                    print(board.listUnits(player_obj))
                except Exception as e:
                    print(f"error moving unit {e}")
                    continue

            # commiting the game saves all input data to yaml for the game setup step
            elif tokens[0] == 'commit':
                if data.clientSave():
                    print("commit complete")
                    break

            # leave
            elif tokens[0] == 'exit':
                sys.exit(0)
            else:
                print("invalid command")
def main(argv):

    # process command line arguments
    if DEBUG:
        print(f"len(argv): {len(argv)}")

    if len(argv) >= 2:
        player_name = '0'
        gameno = argv[1]
    else:
        usage()
        sys.exit(1)

    if len(argv) >= 3:
        board_file = argv[2]
    if len(argv) >= 4:
        player_files = argv[3:]

    # initialize data object
    data = GameData(gameno, player_name)

    while True:

        # load the gamedata
        data.load()

        players = data.getPlayers()
        player_obj = data.getPlayerObj(player_name)
        board = data.getBoard()
        seen_board = data.getSeenBoard()
        size_x = data.getSizeX()
        size_y = data.getSizeY()
        new_game = data.getNewGame()
        game_password = data.getGamePassword()

        # if this is the first time the server is run, you need to reset the initial password from blank here
        password = data.getGamePassword()

        # interactive mode
        while new_game:
            # read line from stdin + tokenize it
            print(f"{argv[0]}> ", flush=True, end='')
            line = sys.stdin.readline().rstrip()
            tokens = line.split()

            # ignore empty lines
            if len(tokens) == 0:
                continue

            # command help
            elif tokens[0] == 'help':
                command_help()
                continue

            # show - board, units
            elif tokens[0] == 'show':
                if DEBUG:
                    print(f"len(tokens): {len(tokens)}")
                if len(tokens) == 1:
                    print("invalid show command")
                    continue
                elif tokens[1] == 'board':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen board")
                        seen_board.print()
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        board.print(player_obj)

                elif tokens[1] == 'types':
                    for player in players.keys():
                        if 'types' in players[player].keys():
                            for types in players[player]['types'].keys():
                                for unit_name in players[player]['types'].keys(
                                ):
                                    unit_type = players[player]['types'][
                                        unit_name]
                                    print(
                                        f"player: {player}, name: {unit_type['name']}, symbol: {unit_type['symbol']}, attack: {unit_type['attack']}, health: {unit_type['health']}, energy: {unit_type['energy']}"
                                    )

                elif tokens[1] == 'players':
                    for player in players.keys():
                        print(
                            f"name: {player}, email: {players[player]['email']}"
                        )
                elif tokens[1] == 'units':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen units")
                        print(seen_board.listUnits())
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        print(board.listUnits(player_obj))
                elif tokens[1] == 'pending':
                    for player in players.keys():
                        if 'moves' in players[player].keys():
                            print(
                                f"player: {player}, moves: {players[player]['moves']}"
                            )
                else:
                    print("invalid show command")
                    continue

            # set - size, player
            elif tokens[0] == 'set':
                if DEBUG:
                    print(f"len(tokens): {len(tokens)}")
                if len(tokens) == 1:
                    print("invalid set command")
                    continue
                elif tokens[1] == 'board':
                    if player_name != '0':
                        print(
                            "only the game admin (player '0') can set board size"
                        )
                        continue
                    if board != None:
                        print("can't resize an existing board")
                        continue
                    if len(tokens) != 4:
                        print("must provide x and y for size")
                        continue
                    try:
                        size_x = int(tokens[2])
                        size_y = int(tokens[3])
                        # immediately create the board object
                        board = Board(size_x, size_y)
                        data.setBoard(board)
                    except:
                        print("x and y must be a numbers")
                        continue
                    if size_x < 2:
                        print("x must be greater than 1")
                    if size_y < 2:
                        print("y must be greater than 1")
                else:
                    print("invalid set command")
                    continue

            # add - player, type, unit
            elif tokens[0] == 'add':
                if len(tokens) == 2:
                    print("invalid add command")
                    continue
                elif tokens[1] == 'player':
                    if len(tokens) != 4:
                        print("must provide 2 args for player")
                    elif new_game == False:
                        print("can't add players to an existing game")
                    else:
                        name = tokens[2]
                        players[name] = {
                            "email": tokens[3],
                            'obj': Player(tokens[2], tokens[3]),
                            'types': {}
                        }
                        password1 = getpass()
                        password2 = getpass("Reenter password: "******"User passwords must match")
                            continue
                        else:
                            players[name]["password"] = password1
                else:
                    print("invalid add command")
                    continue

            # load - player
            elif tokens[0] == 'load':
                if len(tokens) == 2:
                    print("invalid load command")
                    continue
                elif tokens[1] == 'player':
                    if len(tokens) != 3:
                        print("must provide 1 args for load player")
                    elif new_game == False:
                        print("can't add players to an existing game")
                    else:
                        player_data = {}
                        try:
                            with open(tokens[2]) as f:
                                player_data = yaml.safe_load(f)
                                if DEBUG:
                                    print("finished player data")
                        except Exception as e:
                            print(f"Error loading player file {tokens[2]} {e}")
                            continue
                        players[player_data['name']] = {
                            "email":
                            player_data['email'],
                            'obj':
                            Player(player_data['name'], player_data['email']),
                            'password':
                            player_data['password'],
                            'types':
                            player_data['types'],
                            'units':
                            player_data['units']
                        }
                elif tokens[1] == 'board':
                    if len(tokens) != 3:
                        print("must provide 1 args for load board")
                    else:
                        board_data = {}
                        try:
                            with open(tokens[2]) as f:
                                board_data = yaml.safe_load(f)
                                if DEBUG:
                                    print("finished player data")
                        except Exception as e:
                            print(f"Error loading player file {tokens[2]} {e}")
                            continue
                        size_x = int(board_data['board']['size_x'])
                        size_y = int(board_data['board']['size_y'])
                        # immediately create the board object
                        board = Board(size_x, size_y)
                        data.setBoard(board)

                else:
                    print("invalid load command")
                    continue

            # commiting the game saves all input data to yaml for the game setup step
            elif tokens[0] == 'commit':
                # do all the commit actions for the first commit
                if data.serverSave():
                    print("commit complete")
                    break
                else:
                    # commit failed, go back to interactive prompt to resolve problems
                    continue
            # leave
            elif tokens[0] == 'exit':
                sys.exit(0)
            else:
                print("invalid command")

        # do all the commit actions, this will be run when the server is non-interactive
        if new_game:
            # clear the new game flag, this supresses interactive mode for the server
            data.setNewGame(False)
        elif data.serverSave():
            print("commit complete")
        else:
            print("internal server error saving game data")
            sys.exit(1)

        # wait for player commits before restarting the load and commit cycle
        data.waitForPlayerCommit()

        # log board + units
        board.print()
        print(board.listUnits())
def main(argv):

    if DEBUG:
        print(f"len(argv): {len(argv)}")

    if len(argv) == 2:
        player_name = '0'
        gameno = argv[1]
    else:
        usage()
        sys.exit(1)

    # initialize the data object
    data = GameData(gameno, player_name)

    while True:

        # load the gamedata
        data.load()

        players = data.getPlayers()
        player_obj = data.getPlayerObj(player_name)
        board = data.getBoard()
        seen_board = data.getSeenBoard()
        size_x = data.getSizeX()
        size_y = data.getSizeY()
        new_game = data.getNewGame()

        # interactive mode
        while True:
            # read line from stdin + tokenize it
            print(f"{argv[0]}> ", flush=True, end='')
            line = sys.stdin.readline().rstrip()
            tokens = line.split()

            # ignore empty lines
            if len(tokens) == 0:
                continue

            # command help
            elif tokens[0] == 'help':
                command_help()
                continue

            # show - board, units
            elif tokens[0]=='show':
                if DEBUG:
                    print(f"len(tokens): {len(tokens)}")
                if len(tokens) == 1:
                    print("invalid show command")
                    continue
                elif tokens[1] == 'board':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen board")
                        seen_board.print()
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        board.print(player_obj)

                elif tokens[1] == 'types':
                    for player in players.keys():
                        if 'types' in players[player].keys():    
                            for types in players[player]['types'].keys():
                                for unit_name in players[player]['types'].keys():
                                    unit_type = players[player]['types'][unit_name]
                                    print(f"player: {player}, name: {unit_type['name']}, symbol: {unit_type['symbol']}, attack: {unit_type['attack']}, health: {unit_type['health']}, energy: {unit_type['energy']}")

                elif tokens[1] == 'players':
                    for player in players.keys():
                        print(f"name: {player}, email: {players[player]['email']}")
                elif tokens[1] == 'units':
                    if seen_board != None:
                        if DEBUG:
                            print("showing seen units")
                        print(seen_board.listUnits())
                    elif board == None:
                        print("must create board - set size and commit")
                    else:
                        print(board.listUnits(player_obj))
                elif tokens[1] == 'pending':
                    for player in players.keys():
                        if 'moves' in players[player].keys():
                            print(f"player: {player}, moves: {players[player]['moves']}")
                else:
                    print("invalid show command")
                    continue

            # commiting the game saves all input data to yaml for the game setup step
            elif tokens[0] == 'reload':
                # relaod the data
                print("reloading")
                break
            # leave
            elif tokens[0] == 'exit':
                sys.exit(0)
            else:
                print("invalid command")