/*
 * Copyright (c) 2004-2022, University of Oslo
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the HISP project nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.hisp.dhis.webapi.controller.organisationunit;

import static org.hisp.dhis.dxf2.webmessage.WebMessageUtils.conflict;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.hisp.dhis.common.DhisApiVersion;
import org.hisp.dhis.dxf2.metadata.Metadata;
import org.hisp.dhis.dxf2.webmessage.WebMessageException;
import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.webapi.mvc.annotation.ApiVersion;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author Lars Helge Overland
 */
@Controller
@RequestMapping( value = "/filledOrganisationUnitLevels" )
@ApiVersion( { DhisApiVersion.DEFAULT, DhisApiVersion.ALL } )
public class FilledOrganisationUnitLevelController
{
    private final ObjectMapper jsonMapper;

    private final OrganisationUnitService organisationUnitService;

    public FilledOrganisationUnitLevelController(
        ObjectMapper jsonMapper,
        OrganisationUnitService organisationUnitService )
    {
        this.jsonMapper = jsonMapper;
        this.organisationUnitService = organisationUnitService;
    }

    @GetMapping( produces = APPLICATION_JSON_VALUE )
    public @ResponseBody List<OrganisationUnitLevel> getList()
    {
        return organisationUnitService.getFilledOrganisationUnitLevels();
    }

    @PostMapping( consumes = APPLICATION_JSON_VALUE )
    @ResponseStatus( HttpStatus.CREATED )
    public void setList( HttpServletRequest request, HttpServletResponse response )
        throws Exception
    {
        Metadata metadata = jsonMapper.readValue( request.getInputStream(), Metadata.class );

        List<OrganisationUnitLevel> levels = metadata.getOrganisationUnitLevels();

        for ( OrganisationUnitLevel level : levels )
        {
            if ( level.getLevel() <= 0 )
            {
                throw new WebMessageException( conflict( "Level must be greater than zero" ) );
            }

            if ( StringUtils.isBlank( level.getName() ) )
            {
                throw new WebMessageException( conflict( "Name must be specified" ) );
            }

            organisationUnitService.addOrUpdateOrganisationUnitLevel(
                new OrganisationUnitLevel( level.getLevel(), level.getName(), level.getOfflineLevels() ) );
        }
    }
}

@@ -1871,16 +1871,56 @@
 ponse;%0A%0A
+import lombok.RequiredArgsConstructor;%0A%0A
 import o
@@ -2099,24 +2099,135 @@
 eException;%0A
+import org.hisp.dhis.fieldfiltering.FieldFilterParams;%0Aimport org.hisp.dhis.fieldfiltering.FieldFilterService;%0A
 import org.h
@@ -2437,16 +2437,64 @@
 Status;%0A
+import org.springframework.http.ResponseEntity;%0A
 import o
@@ -2709,32 +2709,93 @@
 RequestMapping;%0A
+import org.springframework.web.bind.annotation.RequestParam;%0A
 import org.sprin
@@ -2954,16 +2954,71 @@
 tMapper;
+%0Aimport com.fasterxml.jackson.databind.node.ObjectNode;
 %0A%0A/**%0A *
@@ -3062,16 +3062,41 @@
 troller%0A
+@RequiredArgsConstructor%0A
 @Request
@@ -3382,94 +3382,266 @@
    p
-ublic FilledOrganisationUnitLevelController(%0A        ObjectMapper jsonMapper,
+rivate final FieldFilterService fieldFilterService;%0A%0A    @GetMapping( produces = APPLICATION_JSON_VALUE )%0A    public @ResponseBody ResponseEntity%3CList%3CObjectNode%3E%3E getList(%0A        @RequestParam( defaultValue = %22*%22 ) List%3CString%3E fields )
 %0A   
+ %7B%0A
      
+   List%3C
 Orga
@@ -3644,39 +3644,38 @@
 OrganisationUnit
-Service
+Level%3E
  organisationUni
@@ -3679,75 +3679,17 @@
 Unit
-Service )%0A    %7B%0A        this.jsonMapper = jsonMapper;%0A        this.
+Levels = 
 orga
@@ -3707,20 +3707,27 @@
 tService
- = o
+.getFilledO
 rganisat
@@ -3737,108 +3737,100 @@
 Unit
-Service;
+Levels();%0A
 %0A    
-%7D%0A%0A
     
-@GetMapping( produces = APPLICATION_JSON_VALUE )%0A    public @ResponseBody List%3CO
+FieldFilterParams%3COrganisationUnitLevel%3E params = FieldFilterParams.of( o
 rgan
@@ -3849,97 +3849,151 @@
 evel
-%3E getList()
+s, fields );
 %0A    
-%7B%0A
     
-    return organisationUnitService.getFilledOrganisationUnitLevels(
+List%3CObjectNode%3E objectNodes = fieldFilterService.toObjectNodes( params );%0A%0A        return ResponseEntity.ok( objectNodes 
 );%0A 

add field filtering to filledOrganisationUnitLevels (#12366)