package es.sandwatch.trim;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Class containing all report information.
 *
 * @author Ismael Alonso
 * @version 1.0.0
 */
public class Report{
    private List<EndpointReport> endpointReports;


    /**
     * Constructor.
     */
    Report(){
        endpointReports = new ArrayList<>();
    }

    /**
     * Creates an instance of EndpointReport and adds it to the list.
     *
     * @param endpoint the endpoint associated to the report.
     * @param requestResult the result of the request to the above endpoint.
     * @return the report object.
     */
    @NotNull
    EndpointReport addEndpointReport(@NotNull Endpoint endpoint, @NotNull Trim.RequestResult requestResult){
        EndpointReport report = new EndpointReport(endpoint, requestResult);
        endpointReports.add(report);
        return report;
    }

    @Override
    public String toString(){
        String report = "";
        if (endpointReports.isEmpty()){
            report += "Nothing to report.";
        }
        else{
            report += "Trim report, " + endpointReports.size() + " endpoints:";
            for (EndpointReport endpointReport:endpointReports){
                report += "\n\n" + endpointReport;
            }
        }
        return report;
    }


    /**
     * Report for a single endpoint.
     *
     * @author Ismael Alonso
     * @version 1.0.0
     */
    class EndpointReport{
        private Endpoint endpoint;
        private Trim.RequestResult requestResult;
        private boolean responseFormatError;
        private Map<String, Boolean> attributeReports;


        /**
         * Constructor.
         *
         * @param endpoint the endpoint associated to the report.
         * @param requestResult the result of the request to the above endpoint.
         */
        private EndpointReport(@NotNull Endpoint endpoint, @NotNull Trim.RequestResult requestResult){
            this.endpoint = endpoint;
            this.requestResult = requestResult;
            this.responseFormatError = false;
            this.attributeReports = new HashMap<>();
        }

        /**
         * Lets the report know that the format of the response couldn't be understood.
         */
        void setResponseFormatError(){
            responseFormatError = true;
        }

        /**
         * Adds information about attribute usage to the report.
         *
         * @param attribute the relevant attribute.
         * @param used whether the model uses it.
         */
        void addAttributeReport(@NotNull String attribute, boolean used){
            attributeReports.put(attribute, used);
        }

        @Override
        public String toString(){
            String report = endpoint.toString();
            if (requestResult.requestFailed()){
                report += "\n  The request could not be performed.";
            }
            else{
                report += "\n  Request time: " + requestResult.getRequestTime() + "s";
                report += "\n  Request status code: " + requestResult.getStatusCode();
                if (requestResult.is4xx()){
                    report += "\n  Server response: " + requestResult.getResponse();
                }
                else if (responseFormatError){
                    report += "\n  The format of the response was unknown.";
                }
                else{
                    for (Map.Entry<String, Boolean> entry:attributeReports.entrySet()){
                        report += "\n    " + entry.getKey() + ": " + (entry.getValue() ? "used" : "not used");
                    }
                }
            }
            return report;
        }
    }
}

@@ -1020,32 +1020,39 @@
 %7B%0A        String
+Builder
  report = %22%22;%0A  
@@ -1049,10 +1049,27 @@
 t = 
-%22%22
+new StringBuilder()
 ;%0A  
@@ -1124,20 +1124,24 @@
   report
- += 
+.append(
 %22Nothing
@@ -1152,16 +1152,17 @@
 report.%22
+)
 ;%0A      
@@ -1197,20 +1197,24 @@
   report
- += 
+.append(
 %22Trim re
@@ -1220,19 +1220,25 @@
 eport, %22
- + 
+).append(
 endpoint
@@ -1251,19 +1251,25 @@
 s.size()
- + 
+).append(
 %22 endpoi
@@ -1273,16 +1273,17 @@
 points:%22
+)
 ;%0A      
@@ -1367,21 +1367,31 @@
 port
- += %22%5Cn%5Cn%22 + 
+.append(%22%5Cn%5Cn%22).append(
 endp
@@ -1396,24 +1396,25 @@
 dpointReport
+)
 ;%0A          
@@ -1440,32 +1440,43 @@
    return report
+.toString()
 ;%0A    %7D%0A%0A%0A    /*
@@ -2908,16 +2908,23 @@
   String
+Builder
  report 
@@ -2921,24 +2921,51 @@
 er report = 
+new StringBuilder().append(
 endpoint.toS
@@ -2967,24 +2967,25 @@
 t.toString()
+)
 ;%0A          
@@ -3036,36 +3036,40 @@
           report
- += 
+.append(
 %22%5Cn  The request
@@ -3093,16 +3093,17 @@
 formed.%22
+)
 ;%0A      
@@ -3142,36 +3142,40 @@
           report
- += 
+.append(
 %22%5Cn  Request tim
@@ -3174,27 +3174,33 @@
 uest time: %22
- + 
+).append(
 requestResul
@@ -3221,14 +3221,21 @@
 me()
- + 
+).append(
 %22s%22
+)
 ;%0A  
@@ -3250,28 +3250,32 @@
       report
- += 
+.append(
 %22%5Cn  Request
@@ -3285,27 +3285,33 @@
 atus code: %22
- + 
+).append(
 requestResul
@@ -3327,16 +3327,17 @@
 usCode()
+)
 ;%0A      
@@ -3396,28 +3396,32 @@
       report
- += 
+.append(
 %22%5Cn  Server 
@@ -3431,19 +3431,25 @@
 ponse: %22
- + 
+).append(
 requestR
@@ -3467,16 +3467,17 @@
 sponse()
+)
 ;%0A      
@@ -3557,28 +3557,32 @@
       report
- += 
+.append(
 %22%5Cn  The for
@@ -3614,16 +3614,17 @@
 nknown.%22
+)
 ;%0A      
@@ -3779,47 +3779,101 @@
 port
- += %22%5Cn    %22 + entry.getKey() + %22: %22 + 
+.append(%22%5Cn    %22).append(entry.getKey()).append(%22: %22)%0A                                .append
 (ent
@@ -3985,24 +3985,35 @@
 eturn report
+.toString()
 ;%0A        %7D%0A

Optimize toStrings()