import requests
import json
import time


def fetch_json(path, payload, call_count=1):
  """Send a request to the server and return the parsed JSON response."""

  # it's polite to self-identify this "bot"
  delphi_url = 'https://delphi.midas.cs.cmu.edu/index.html'
  user_agent = 'Mozilla/5.0 (compatible; delphibot/1.0; +%s)' % delphi_url

  # the FluSurv AMF server
  flusurv_url = 'https://gis.cdc.gov/GRASP/Flu3/' + path

  # request headers
  headers = {
    'Accept-Encoding': 'gzip',
    'User-Agent': user_agent,
  }
  if payload is not None:
    headers['Content-Type'] = 'application/json;charset=UTF-8'

  # send the request and read the response
  if payload is None:
    method = requests.get
    data = None
  else:
    method = requests.post
    data = json.dumps(payload)
  resp = method(flusurv_url, headers=headers, data=data)

  # check the HTTP status code
  if resp.status_code == 500 and call_count <= 2:
    # the server often fails with this status, so wait and retry
    delay = 10 * call_count
    print('got status %d, will retry in %d sec...' % (resp.status_code, delay))
    time.sleep(delay)
    return fetch_json(path, payload, call_count=call_count + 1)
  elif resp.status_code != 200:
    raise Exception(['status code != 200', resp.status_code])

  # check response mine type
  if 'application/json' not in resp.headers.get('Content-Type', ''):
    raise Exception('response is not json')

  # return the decoded json object
  return resp.json()