import json
import requests
import socket
import sys

GET_URL = "https://api.gameupc.com/test/upc/{}"
SEARCH_URL = "https://api.gameupc.com/test/upc/{}?search={}"
API_HEADERS = {"x-api-key": "test_test_test_test_test"}


# Get the input UPC; normally, you would use your apps' scanner interface, and
#   capture any UPCs found.  Depending on the application, you could stop once
#   you got the first UPC, or add them to a list to process asynchronously (if we
#   were cataloging a whole bunch of games, for example)
upc = input("Enter a UPC (or blank for 19962194719):")
if upc == '':
    # Note that there are some special UPCs that are useful for testing your
    #    software:
    #    111111111111 (or 1) is a game that has a strong recommended value
    #    222222222222 (or 2) is a game that has some data, but we need to prompt the user
    #    333333333333 (or 3) is a game where our upc lookup has failed to return data
    upc = '19962194719';

# Fetch data from gameupc.com.  The endpoints are documented at https://gameupc.com/#api
response = requests.get(GET_URL.format(upc), headers=API_HEADERS)
response.raise_for_status()
data = json.loads(response.text)

# If we have a good result, the bgg_info_status field will be 'verified'
while data['bgg_info_status'] != 'verified':
    # If we're not completely sure, our heuristics will suggest some games and
    #    the user will need to choose from one of the options in bgg_info,
    #    or they can enter new search terms to find the right game
    if len(data['bgg_info']) > 0:
        print("Game suggestions for {} (searching for '{}')".format(upc, data['searched_for']))
        for n, item in enumerate(data['bgg_info']):
            print('     {} - {}'.format(n + 1, item['name']))

        choice = input('1-{} to select your game, or new search terms: '.format(len(data['bgg_info'])));
    else:
        print("For {}, could not find any games for '{}'".format(upc, data['searched_for']))
        choice = input('Please enter new search terms: ')

    if choice == '':
        continue
    else:
        # Check to see if the user chose a number
        intVal = None
        try:
            intVal = int(choice) - 1
        except ValueError:
            pass

        if intVal is not None:
            # If the user made a choice, update the data for anybody else that
            #    searches for this UPC.  It generally takes two uncontested votes
            #    for a UPC->bgg_id mapping to be considered "good"
            choice_data = data['bgg_info'][intVal]

            bgg_id = choice_data['id']
            # For noise prevention, we need a consistent user_id that can identify
            #    badly-behaved users.  For this demo, we'll use the local hostname
            user_id = 'hostname-' + socket.gethostname()

            # The URL to update the data is included as part of the json response
            #    in the update_url field.  We need to send a json body (not form data)
            #    that has the user_id field populated
            response = requests.post(choice_data['update_url'], json={'user_id': user_id}, headers=API_HEADERS)
            response.raise_for_status()

            # The response will contain the updated data, with the bgg_info_status field set
            data = json.loads(response.text)
        else:
            # If our heuristics didn't get the right game name, the user can enter
            #    some suggestions, and gameupc.com will return the information
            #    related to that search
            response = requests.get(SEARCH_URL.format(upc, choice), headers=API_HEADERS)
            response.raise_for_status()

            data = json.loads(response.text)

# We got a good choice for the user!  Your app would use this for the game information
#   and create a smooth scanning experience.
result = data['bgg_info'][0]
print('Your selected game is {}, BGG number {}'.format(result['name'], result['id']))
