# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#!/usr/bin/env python
"""
This is an example of how a script might make calls to monorail's v3  pRPC API.

Usage example:
```
python v3_test_call.py \
monorail.v3.Issues GetIssue '{"name": "projects/monorail/issues/404"}'
```

The email of your service account should be allow-listed with Monorail.
"""

import argparse
import json
import logging
import os
import requests


# Older versions of https://github.com/googleapis/google-auth-library-python
# do not have the fetch_id_token() method called below.
# v1.15.0 or later should be fine.
from google.oauth2 import id_token
from google.auth.transport import requests as google_requests

# Download and save your service account credentials file in
# api/service-account-key.json.
# id_token.fetch_id_token looks inside GOOGLE_APPLICATION_CREDENTIALS to fetch
# service account credentials.
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'service-account-key.json'

# BASE_URL can point to any monorail-dev api service version.
# However, you MAY get ssl cert errors when BASE_URL is not the
# default below. If this happens you will have to test your version
# by using the existing BASE_URL and migrating all traffic to your api
# version via pantheon.
BASE_URL = 'https://api-dot-monorail-dev.appspot.com/prpc'

# TARGET_AUDIENCE should not change as long as BASE_URL is pointing to
# some monorail-dev version. If BASE_URL is updated to point to
# monorail-{staging|prod}, update TARGET_AUDIENCE accordingly.
TARGET_AUDIENCE = 'https://monorail-dev.appspot.com'

# XSSI_PREFIX found at the beginning of every prpc response.
XSSI_PREFIX = ")]}'\n"

import httplib2
from oauth2client.client import GoogleCredentials


def make_call(service, method, json_body):
  # Fetch ID token
  request = google_requests.Request()
  token = id_token.fetch_id_token(request, TARGET_AUDIENCE)
  # Note: ID tokens for service accounts can also be fetched with with the
  # Cloud IAM API projects.serviceAccounts.generateIdToken
  # generateIdToken only needs the service account email or ID and the
  # target_audience.

  # Call monorail's API.
  headers = {
      'Authorization': 'Bearer %s' % token,
      'Content-Type': 'application/json',
      'Accept': 'application/json',
  }

  url = "%s/%s/%s" % (BASE_URL, service, method)

  body = json.loads(json_body)
  resp = requests.post(url, data=json.dumps(body), headers=headers)
  logging.info(resp)
  logging.info(resp.text)
  logging.info(resp.content)
  logging.info(json.dumps(json.loads(resp.content[len(XSSI_PREFIX):])))

  # Verify and decode ID token to take a look at what's inside.
  # API users should not have to do this. This is just for learning about
  # how ID tokens work.
  request = google_requests.Request()
  id_info = id_token.verify_oauth2_token(token, request)
  logging.info('id_info %s' % id_info)


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.')
  args = parser.parse_args()
  log_level = logging.INFO
  logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)
  make_call(args.service, args.method, args.json_body)
