#!/usr/bin/env python3

"""APIClient.py: Client for the IBM QRadar API"""
__author__      = "Radek Hranicky"

import logging
import sys
import os
import requests

import socket
import requests.packages.urllib3.util.connection as urllib3_cn
import urllib3
import json

logger = logging.getLogger('domainradar')

class APIClient:
    def __init__(self, config):
        """
        ! Constructor of the QRadar REST API client class
        @param config Application config object
        """
        self.config = config

        # Hack no.1: FORCE IPV4
        if (config.force_ipv4):
            def allowed_gai_family():
                family = socket.AF_INET # force IPv4
                return family
            urllib3_cn.allowed_gai_family = allowed_gai_family

        # Hack no.2: Disable warning about insecure HTTPS context
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def request_get(self, endpoint, request_params=dict()):
        """
        ! Makes a GET request on the given endpoint
        @param endpoint Identifier of the endpoint to contact
        @param request_parms Dictionary of request parameters (optional)
        @return Result or None in case of an error
        """
        if endpoint[0] != '/':
            endpoint = '/' + endpoint
        request_url = self.config.get_api_url() + str(endpoint)
        request_headers = {#'Range': 'items=0-49',
            'SEC': self.config.get_sec_token(),
            'Version': self.config.get_api_version(),
            'Accept': 'application/json'
        }
        response = requests.get(url=request_url, headers=request_headers, params=request_params, verify=False)
        if response.status_code < 200 or response.status_code > 299:
            logger.error("Request on endpoint '" + endpoint + "' failed!")
            return None
        return response.json()


    def request_post(self, endpoint, request_params=dict(), post_data=None, post_json=None):
        """
        ! Makes a POST request on the given endpoint
        @param endpoint Identifier of the endpoint to contact
        @param request_parms Dictionary of request parameters (optional)
        @param post_data A dictionary, list of tuples, bytes or a file object to send (optional)
        @param post_json A JSON object to send (optional alternative)
        @return Result or None in case of an error
        """
        if endpoint[0] != '/':
            endpoint = '/' + endpoint
        request_url = self.config.get_api_url() + str(endpoint)
        request_headers = {
            'SEC': self.config.get_sec_token(),
            'Version': self.config.get_api_version(),
            'Accept': 'application/json'
        }
        params = dict()
        params.update(request_params)
        response = requests.post(url=request_url, headers=request_headers, params=request_params, data=post_data, json=post_json, verify=False)
        if response.status_code < 200 or response.status_code > 299:
            logger.error("Request on endpoint '" + endpoint + "' failed!")
            return None
        return response.json()
