<commit_before>﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using Nancy;

namespace Concord
{
    public class PactProviderNancyModule : NancyModule
    {
        private static PactProviderRequest _request;
        private static PactProviderResponse _response;

        public PactProviderNancyModule()
        {
            if (_request == null || _response == null)
            {
                return;
            }
            
            switch (_request.Method)
            {
                case HttpVerb.Head:
                case HttpVerb.Get:
                    Get[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Post:
                    Post[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Put:
                    Put[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Delete:
                    Delete[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Patch:
                    Patch[_request.Path] = _ => HandleRequest();
                    break;
            }
        }

        public static void Set(PactProviderRequest request, PactProviderResponse response)
        {
            _request = request;
            _response = response;
        }

        private Response HandleRequest()
        {
            this.FilterRequest();
            return this.GenerateResponse();
        }

        private Response GenerateResponse()
        {
            var mapper = new NancyResponseMapper();
            return mapper.Convert(_response);
        }

        private void FilterRequest()
        {
            if (_request == null)
                throw new Exception("Pact Request not set");

            // TODO: Handle in a better way and return mismatches
            this.CompareHeaders();
            this.CompareBody();
        }

        private void CompareHeaders()
        {
            foreach (var providerHeader in _request.Headers)
            {
                // Check header exists in Nancy Headers
                var nancyHeader = this.Request.Headers.FirstOrDefault(header => header.Key == providerHeader.Key);

                // If matching nancy header doesn't exist return false
                if (!nancyHeader.Value.Contains(providerHeader.Value))
                    throw new Exception("Nancy Pact Request Header Mismatch");
            }
        }

        private void CompareBody()
        {
            using (var reader = new StreamReader(this.Request.Body, Encoding.UTF8))
            {
                var nancyBody = reader.ReadToEnd();
                var pactBody = _request.Body != null ? Newtonsoft.Json.JsonConvert.SerializeObject(_request.Body) : string.Empty;

                if (!nancyBody.Equals(pactBody, StringComparison.InvariantCultureIgnoreCase))
                    throw new Exception("Nancy Pact Request Body Mismatch");
            }
        }

        private static void Reset()
        {<commit_msg>Added a more verbose error to the Nancy Module when Pact headers don't match.<commit_after>﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using Nancy;

namespace Concord
{
    public class PactProviderNancyModule : NancyModule
    {
        private static PactProviderRequest _request;
        private static PactProviderResponse _response;

        public PactProviderNancyModule()
        {
            if (_request == null || _response == null)
            {
                return;
            }
            
            switch (_request.Method)
            {
                case HttpVerb.Head:
                case HttpVerb.Get:
                    Get[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Post:
                    Post[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Put:
                    Put[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Delete:
                    Delete[_request.Path] = _ => HandleRequest();
                    break;
                case HttpVerb.Patch:
                    Patch[_request.Path] = _ => HandleRequest();
                    break;
            }
        }

        public static void Set(PactProviderRequest request, PactProviderResponse response)
        {
            _request = request;
            _response = response;
        }

        private Response HandleRequest()
        {
            this.FilterRequest();
            return this.GenerateResponse();
        }

        private Response GenerateResponse()
        {
            var mapper = new NancyResponseMapper();
            return mapper.Convert(_response);
        }

        private void FilterRequest()
        {
            if (_request == null)
                throw new Exception("Pact Request not set");

            // TODO: Handle in a better way and return mismatches
            this.CompareHeaders();
            this.CompareBody();
        }

        private void CompareHeaders()
        {
            foreach (var providerHeader in _request.Headers)
            {
                // Check header exists in Nancy Headers
                var nancyHeader = this.Request.Headers.FirstOrDefault(header => header.Key == providerHeader.Key);

                // If matching nancy header doesn't exist return false
                if (!nancyHeader.Value.Contains(providerHeader.Value))
                    throw new Exception("Pact Request Header Not Found in Nancy Request: " + providerHeader.Key + " " + providerHeader.Value);
            }
        }

        private void CompareBody()
        {
            using (var reader = new StreamReader(this.Request.Body, Encoding.UTF8))
            {
                var nancyBody = reader.ReadToEnd();
                var pactBody = _request.Body != null ? Newtonsoft.Json.JsonConvert.SerializeObject(_request.Body) : string.Empty;

                if (!nancyBody.Equals(pactBody, StringComparison.InvariantCultureIgnoreCase))
                    throw new Exception("Nancy Pact Request Body Mismatch");
            }
        }

        private static void Reset()
        {
{'fraction_non_alphanumeric': 0.07940525150268903, 'fraction_numerical': 0.00031635558367605187, 'mean_word_length': 1.4796078431372548, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3848234', 'n_tokens_mistral': 1507, 'n_tokens_neox': 1418, 'n_words': 374}