import requests
import json
import pytest
import assertions
import curlify

HOST_URL = "{{ host_url }}"

responses_recieved = []

def _prep_data_for_fuzzing(file, params_list):
    fuzz_values = []
    with open(file, encoding="iso-8859-15") as fobj:
        values = [str(_).replace("\n","") for _ in fobj.readlines()]
    no_of_params = len(params_list)
    for _ in values:
        fuzz_values.append([_]*no_of_params)
    print("Fuzz values for "+str(file)+": "+str(fuzz_values))
    return fuzz_values

def _trigger_requests(req_method, url, header, data, proxies=None):
    print("\n\nRegenerating traffic from CloudVector events....")
    return requests.request(method=req_method, url=url, proxies=proxies, headers=header, data=data, verify=False)

def _create_curl_request(url,method,headers,payloads):
    # construct the curl command from request
    command = "curl -v -H {headers} {data} -X {method} {uri}"
    data = ""
    if payloads:
        payloads = json.loads(payloads)
        payload_list = ['"{0}":"{1}"'.format(k,v) for k,v in payloads.items()]
        data = " -d '{" + ", ".join(payload_list) + "}'"
    header_list = ['"{0}: {1}"'.format(k, v) for k, v in headers.items()]
    header = " -H ".join(header_list)
    return command.format(method=method, headers=header, data=data, uri=url)

{% for fuzz_info in fuzzing_details %}
{% set api_name = api_name | replace("{","") | replace("}","") %}
@pytest.mark.parametrize("{{ api_info.get("params",[])|join(", ") }}", _prep_data_for_fuzzing("{{ fuzz_info.get("file") }}", {{ api_info.get("params",[]) }}))
def test_{{ api_name }}_for_{{ fuzz_info.get("fuzz_type") }}({{ api_info.get("params",[])|join(", ") }}):
    data = {}
    {% for param in api_info.get("params",[]) %}data["{{ param }}"] = {{ param }}
    {% endfor %}
    headers = {{ api_info.get("header") }}
    headers["cv-fuzzed-event"] = "1"
    req = {
             "data": data,
             "headers": headers
          }
    resp = _trigger_requests("{{ api_info.get("method") }}", "{{ api_info.get("url") }}",
                      header=req["headers"],
                      data=json.dumps(data))
    responses_recieved.append(resp)
    print(resp.status_code)
    print(resp.text)
    assertions.assert_for_negative_scenarios(req,resp)
{% endfor %}

def test_for_anomalies():
    pattern_observed = {"status_code": [], "resp_size": [], "request":[], "fuzz_type": "{{ fuzz_type }}"}
    for resp in responses_recieved:
        pattern_observed["status_code"].append(resp.status_code)
        pattern_observed["resp_size"].append(len(resp.content))
        #pattern_observed["request"].append(_create_curl_request(resp.request.url,resp.request.method,resp.request.headers,resp.request.body))
        pattern_observed["request"].append(curlify.to_curl(resp.request))
    assertions.assert_for_anomalies(pattern_observed)


