#!/usr/bin/env python
"""
This is a helper script for making pRPC API calls during local development.

Usage examples:

To test an anonymous request to your own local monorail server:
1. Run 'make serve' in another shell
2. `./api/test_call monorail.Projects ListComponents
     '{"project_name": "monorail", "include_admin_info": true}'`

To test a signed in request to your own local monorail server:
1. Run 'make serve' in another shell
2. `./api/test_call monorail.Projects ListComponents
     '{"project_name": "monorail", "include_admin_info": true}'
     --test_account=test@example.com`
Note that test account email address must always end in @example.com.

To test an anonymous request to your monorail staging server:
1. Deploy your staging server version, e.g., 12345-76697e9-tainted-jrobbins.
2. Visit your staging server in a new incognito window and view source
   to find the XSRF token for the anonymous user in JS var CS_env['token'].
3. `./api/test_call monorail.Projects ListComponents
    '{"project_name": "monorail", "include_admin_info": true}'
    --host=12345-76697e9-tainted-jrobbins-dot-monorail-staging.appspot.com
    --xsrf-token='THE_ANON_TOKEN'`

To test a signed-in request to your monorail staging server using
the client_id for monorail-staging and your own account:
1. Make sure that you have a role in the monorail-staging project.
2. Have your account allowlisted by email address.
3. Download the monorail-staging app credientials via
   `gcloud --project=monorail-staging auth login`.
4. `./api/test_call monorail.Projects ListComponents
    '{"project_name": "monorail", "include_admin_info": true}'
    --host=12345-76697e9-tainted-jrobbins-dot-monorail-staging.appspot.com
    --use-app-credentials`

To test a signed-in request to your monorail staging server using
a service account client secrets file that you download:
(Note: This is not recommended for prod because downloading secrets
is a bad practice.)
1. Create a service account via the Cloud Console for any project.
   Choose "IAM & Admin" > "Service accounts".
   Press "+ Create Service Account".
   Fill in the form and submit it to save a service account .json file
   to your local disk.  Keep this file private.
2. File an issue on /p/monorail to allowlist your client_id and/or
   client_email.  Or, author a CL yourself to add it to the allowlist.
3. `./api/test_call monorail.Projects ListComponents
    '{"project_name": "monorail", "include_admin_info": true}'
    --host=12345-76697e9-tainted-jrobbins-dot-monorail-staging.appspot.com
    --service-account=FILENAME_OF_SERVICE_ACCOUNT_JSON_FILE`
"""

import argparse
import errno
import json
import logging
import os
import sys


monorail_dir = os.path.dirname(os.path.abspath(__file__ + '/..'))
third_party_path = os.path.join(monorail_dir, 'third_party')
if third_party_path not in sys.path:
  sys.path.insert(0, third_party_path)

import httplib2
from oauth2client.client import GoogleCredentials


URL_BASE = 'http://localhost:8080/prpc/'
OAUTH_SCOPE = 'https://www.googleapis.com/auth/userinfo.email'

def make_http(args):
  """Return an httplib2.Http object, with or without oauth."""
  http = httplib2.Http()
  credentials = None
  if args.use_app_credentials:
    credentials = GoogleCredentials.get_application_default()
  if args.service_account:
    credentials = GoogleCredentials.from_stream(args.service_account)
    logging.debug('Will request as user %r', credentials.service_account_email)

  if credentials:
    credentials = credentials.create_scoped([OAUTH_SCOPE])
    logging.debug('Will request as client %r', credentials.client_id)
    if not args.host:
      print(('[ERROR] OAuth on localhost will always see user '
             'example@example.com, so we do not support that.\n'
             'Instead, add --server=YOUR_STAGING_SERVER, '
             'or use --test_account=USER@example.com.'))
      sys.exit(1)

    http = credentials.authorize(http)

  return http

def make_call(service, method, json_body, args):
  """Call the server and print the response contents."""
  body = json.loads(json_body)

  url_base = URL_BASE
  if args.host:
    url_base = 'https://%s/prpc/' % args.host
  url = '%s%s/%s' % (url_base, service, method)
  logging.debug('Request URL: %s', url)

  http = make_http(args)
  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      }
  if args.test_account:
    headers['x-test-account'] = args.test_account
  if args.xsrf_token:
    headers['x-xsrf-token'] = args.xsrf_token
  body = json.dumps(body)

  logging.debug('Body: %r' % body)
  try:
    response, contents = http.request(
        url, method='POST', body=body, headers=headers)
    logging.info('Received response: %s', contents)
  except httplib2.HttpLib2Error as e:
    if hasattr(e.reason, 'errno') and e.reason.errno == errno.ECONNREFUSED:
      print('[Error] Could not reach server. Is it running?')
    else:
      raise e


if __name__ == '__main__':
  parser = argparse.ArgumentParser(description='Process some integers.')
  parser.add_argument('service', help='pRPC service name.')
  parser.add_argument('method', help='pRPC method name.')
  parser.add_argument('json_body', help='pRPC HTTP body in valid JSON.')
  parser.add_argument('--test-account',
      help='Test account to use, in the form of an email.')
  parser.add_argument('--xsrf-token', help='Custom XSRF token.')
  parser.add_argument('--host', help='remote server FQDN.')
  parser.add_argument(
      '--use-app-credentials',
      help='Use credentials of a GAE app that you are signed into via gcloud.',
      action='store_true')
  parser.add_argument(
      '--service-account', help='Service account credentials JSON file name.')
  parser.add_argument('-v', '--verbose', action='store_true')
  args = parser.parse_args()

  if args.verbose:
    log_level = logging.DEBUG
  else:
    log_level = logging.INFO
  logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)

  make_call(args.service, args.method, args.json_body, args)
