/*
** Module   : HttpResponseBody.java
** Abstract : A test for the HTTP response body.
**
** Copyright (c) 2021, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
** 001 CA  20210827 Created initial version.
*/

/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.goldencode.harness.test;

import java.util.*;

import org.apache.http.*;

import com.goldencode.harness.*;

/**
 * A test applied to the response body; paths can be applied  when the body is traversable (i.e. a XML or JSON 
 * structure).
 * <p>
 * It checks that the body matches the given template, using the specified excluded or included paths.
 */
public class HttpResponseBody
extends Report
implements WebResponseTestable
{
   /** The expected response body. */
   private String body;

   /** The variable where to save the actual response, if it passes the test. */
   private String variable;
   
   /** The list of excluded paths (and all their children). */
   private List<String> excludes;
   
   /** The list of included paths (and all their children). */
   private List<String> includes;

   /** The resource pool to store the variable. */
   private ResourcePool pool;

   /** The associated web service. */
   private WebService service;

   /**
    * Configure a new response body test.
    * 
    * @param    body
    *           The response body template.
    * @param    variable
    *           The variable where to save the body.
    * @param    excludes
    *           The list of excluded paths.
    * @param    includes
    *           The list of included paths.
    * @param    service
    *           The associated web service.
    */
   public HttpResponseBody(String       body,
                           String       variable,
                           List<String> excludes,
                           List<String> includes,
                           WebService   service)
   {
      if (body == null)
      {
         throw new NullPointerException("Must specify the expected response body!");
      }
      this.body     = body;
      this.variable = variable;
      this.excludes = excludes;
      this.includes = includes;
      this.pool     = service.getResourcePool();
      this.service  = service;
   }

   /**
    * Execute the test, by checking if the body {@link WebService#checkBodyMatch matches}.
    * 
    * @param    response
    *           The HTTP response.
    */
   @Override
   public void execute(HttpResponse response)
   {
      setStatus(Status.PASSED, null);
      
      String responseBody = service.getResponseBody();
      if (!body.isEmpty() && (responseBody == null || responseBody.isEmpty()))
      {
         setStatus(Status.FAILED, "No response body received.");
         return;
      }
      
      String failures = service.checkBodyMatch(body, includes, excludes);
      if (failures == null)
      {
         if (variable != null)
         {
            pool.createVariable(variable, body);
         }
      }
      else
      {
         setStatus(Status.FAILED, "Body match failed:\n" + failures);
      }
   }
}
