package com.tecnalia.DVPolicyEngine.api;

import com.tecnalia.DVPolicyEngine.model.Access;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tecnalia.DVPolicyEngine.model.Input;
import com.tecnalia.DVPolicyEngine.service.PolicyService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.*;
import javax.validation.Valid;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;

@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2021-07-16T07:58:35.159Z[GMT]")
@RestController

public class GetAccessApiController implements GetAccessApi {

    private static final Logger log = LoggerFactory.getLogger(GetAccessApiController.class);

    private final ObjectMapper objectMapper;

    private final HttpServletRequest request;

    @Autowired
    private  PolicyService policyService;
    
    @org.springframework.beans.factory.annotation.Autowired
    public GetAccessApiController(ObjectMapper objectMapper, HttpServletRequest request) {
        this.objectMapper = objectMapper;
        this.request = request;
    }
       public ResponseEntity<List<Access>> getAccessByAttributes(@Parameter(in = ParameterIn.DEFAULT, description = "", required=true, schema=@Schema()) @Valid @RequestBody Input body) {
  //  public ResponseEntity<List<Access>> getAccessByAttributes(@NotNull @Parameter(in = ParameterIn.QUERY, description = "" ,required=true,schema=@Schema()) @Valid @RequestParam(value = "DatasetID_list", required = true) List<String> datasetIDList,@NotNull @Parameter(in = ParameterIn.QUERY, description = "" ,required=true,schema=@Schema()) @Valid @RequestParam(value = "DataSeekerID", required = true) String dataSeekerID) {
    
        
        String accept = request.getHeader("Accept");
        String dataSeekerID="";
        String organizationAttributesAsString="";   
        List<String> datasetIDList=null;
     /* 1.-GetDataSeekersOrganisationPolicy (DataSeekerID)  -> de aqui obtenemos los atributos de la organización
     
      */
     
  /*   {  
   "dataseekerID":"462626262",
   "DatasetIDs":[
      "1421515",
      "616266262"
   ]
}*/    try{
            dataSeekerID=body.getDataseekerID();
            organizationAttributesAsString=policyService.getDataSeekersOrganizationPolicy(dataSeekerID);
            
         //  organizationAttributesAsString="{\"name\":\"Test Organization\",\"sector\":\"Test Sector\",\"continent\":\"EU\",\"country\":\"GRE\",\"type\":\"Private Entity\",\"size\":\"medium\",\"reputation\":7}";
            
            System.out.println("organizationAttributesAsString:"+organizationAttributesAsString);
            
            datasetIDList=new ArrayList<String>();
            datasetIDList=body.getDatasetIDs();
            
            
        }
        catch(Exception e){
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); 
        }
     
        
      
      //  organizationAttributesAsString="{\"name\":\"Test Organization\",\"sector\":\"Test Sector\",\"continent\":\"EU\",\"country\":\"GRE\",\"type\":\"Private Entity\",\"size\":\"medium\",\"reputation\":7}";
        
      
       
      
       
        
     /*"
        2.- GetDatasetPolicies (DatasetID) -> de aqui obtendremos la politica con la siguiente información. -> llamada a API blockchain
            struct access_policy {
                    string[] Sector;
                    string[] Continent;
                    string[] Country;
                    string[] Type;
                    string[] Size;
                    string[] Reputation_Score;
            }
*/
        
     
     
     
     
     
        JSONObject organizationAttributesJson = null;
        JSONObject accessPolicyAsJSON = null;
        List<Access> listAccess =new ArrayList<Access>();
        try{ 
            
            
            organizationAttributesJson=new JSONObject(organizationAttributesAsString);
            
            
            
        
            for (String datasetID : datasetIDList) {

                String accessPolicyasString=policyService.getDatasetPolicy(datasetID);
                
                //String accessPolicyasString="{\"Continent\":[\"testContinent\",\"test2Continent\"],\"Type\":[\"testType\",\"test2Type\"],\"Sector\":[\"testSector\",\"test2Sector\"],\"Size\":[\"testSize\",\"test2Size\"],\"Country\":[\"testCountry\",\"test2Country\"],\"Reputation\":0}";
                
                
                
                try
                {
                    accessPolicyAsJSON = new JSONObject(accessPolicyasString);

                    System.out.println("accessPolicyasString:"+accessPolicyasString);

                        // 3.-Comparar los atributos de la organización con los de la politica y construir el objeto Access y añadirlo a la lista

                    Access access=policyService.checkAtributesInPolicy( datasetID, organizationAttributesJson,  accessPolicyAsJSON);
                    if (access!=null)     
                        listAccess.add(access);



                }
                catch(Exception e){
                    Access access=new Access();
                    access.datasetID(datasetID);
                    access.setGranted(Boolean.FALSE);
                    access.setNonConformities(accessPolicyasString);
                    listAccess.add(access);
                    //return new ResponseEntity<List<Access>>(listAccess, HttpStatus.INTERNAL_SERVER_ERROR); 
                }

            }   
            
            
            
        }catch (Exception e){
              
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); 
            
        }
        
        
        
        
         
        return new ResponseEntity<List<Access>>(listAccess, HttpStatus.OK); 
        
        
    }

}