#!/usr/bin/env python

"""REST: Simple command line interface to testing RESTful services.

usage: REST [-h] [--cookie COOKIE] [--header HEADER] [--data DATA]
            {GET,POST,PUT,PATCH,DELETE} url

REST API Tester

positional arguments:
  {GET,POST,PUT,PATCH,DELETE}
                        The HTTP method to use
  url                   The URL to request

optional arguments:
  -h, --help            show this help message and exit
  --cookie COOKIE, -c COOKIE
                        Specify an HTTP cookie value in NAME=VALUE format.
  --header HEADER, -H HEADER
                        Add custom HTTP request headers in 'Name: Value'
                        format.
  --data DATA, -d DATA  JSON data to be sent with the request.

Examples:
    REST GET http://localhost/v1/resource/item
    REST POST http://localhost/v1/resource -d '{"hello": "world"}'
"""

import argparse
import requests
import json

def main():
    parser = argparse.ArgumentParser(description="REST API Tester")
    parser.add_argument(
        "--cookie", "-c",
        action="append",
        help="Specify an HTTP cookie value in NAME=VALUE format.",
    )
    parser.add_argument(
        "--header", "-H",
        action="append",
        help="Add custom HTTP request headers in 'Name: Value' format.",
    )
    parser.add_argument(
        "--data", "-d",
        default=None,
        help="JSON data to be sent with the request.",
    )
    parser.add_argument(
        "method",
        help="The HTTP method to use",
        choices=["GET", "POST", "PUT", "PATCH", "DELETE"],
    )
    parser.add_argument(
        "url",
        help="The URL to request",
    )
    args = parser.parse_args()

    # Convert cookie/header params.
    if args.header:
        args.header = strings_to_dict(args.header, ":")
    if args.cookie:
        args.cookie = strings_to_dict(args.cookie, "=")

    do_http(args)


def do_http(args):
    result = None

    headers = {
        "Content-Type": "application/json",
    }
    if args.header:
        headers.update(args.header)

    result = getattr(requests, args.method.lower())(
        args.url,
        headers=headers,
        cookies=args.cookie,
        data=args.data,
    )

    print args.method, args.url, result.status_code

    # JSON response?
    try:
        parsed = result.json
        print json.dumps(parsed,
            sort_keys=True,
            indent=4,
            separators=(',', ': '),
        )
    except:
        print result.text


def strings_to_dict(strings, separator):
    """Turn a list of key/value pairs into a dictionary."""
    result = dict()
    for item in strings:
        k, v = item.split(separator)
        k = k.strip()
        v = v.strip()
        result[k] = v
    return result

if __name__ == "__main__":
    main()