/*
 * Copyright 2016-2019 52°North Initiative for Geospatial Open Source
 * Software GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.n52.javaps.service.handler;

import static java.util.stream.Collectors.toSet;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import javax.inject.Inject;

import org.n52.shetland.ogc.ows.exception.OwsExceptionReport;
import org.n52.shetland.ogc.ows.OwsAllowedValues;
import org.n52.shetland.ogc.ows.OwsCode;
import org.n52.shetland.ogc.ows.OwsDomain;
import org.n52.shetland.ogc.ows.OwsValue;
import org.n52.shetland.ogc.wps.ProcessOffering;
import org.n52.shetland.ogc.wps.ProcessOfferings;
import org.n52.shetland.ogc.wps.WPSConstants;
import org.n52.iceland.request.handler.GenericOperationHandler;
import org.n52.iceland.request.handler.OperationHandlerKey;
import org.n52.javaps.engine.Engine;
import org.n52.shetland.ogc.wps.request.DescribeProcessRequest;
import org.n52.shetland.ogc.wps.response.DescribeProcessResponse;

/**
 * TODO JavaDoc
 *
 * @author Christian Autermann
 */
public class DescribeProcessHandler extends AbstractEngineHandler implements GenericOperationHandler<
        DescribeProcessRequest, DescribeProcessResponse> {
    private static final String IDENTIFIER = "Identifier";

    private static final OperationHandlerKey KEY = new OperationHandlerKey(WPSConstants.SERVICE,
            WPSConstants.Operations.DescribeProcess);

    @Inject
    public DescribeProcessHandler(Engine engine) {
        super(engine);
    }

    @Override
    public DescribeProcessResponse handle(DescribeProcessRequest request) throws OwsExceptionReport {

        Set<ProcessOffering> offerings = request.getProcessIdentifier().stream().map(getEngine()::getProcessDescription)
                .filter(Optional::isPresent).map(Optional::get).map(ProcessOffering::new).collect(toSet());

        return new DescribeProcessResponse(request.getService(), request.getVersion(), new ProcessOfferings(offerings));
    }

    @Override
    public String getOperationName() {
        return WPSConstants.Operations.DescribeProcess.toString();
    }

    @Override
    public Set<OperationHandlerKey> getKeys() {
        return Collections.singleton(KEY);
    }

    @Override
    protected Set<OwsDomain> getOperationParameters(String service,
            String version) {
        Stream<OwsValue> specialIdentifiers = Stream.of(new OwsValue(DescribeProcessRequest.ALL_KEYWORD));
        Stream<OwsValue> algorithmIdentifiers = getEngine().getProcessIdentifiers().stream().map(OwsCode::getValue).map(
                OwsValue::new);
        OwsDomain identifierDomain = new OwsDomain(IDENTIFIER, new OwsAllowedValues(Stream.concat(specialIdentifiers,
                algorithmIdentifiers).collect(toSet())));
        return Collections.singleton(identifierDomain);
    }

    @Override
    public boolean isSupported() {
        return true;
    }

}

@@ -895,53 +895,152 @@
 n52.
-shet
+ice
 land.
-ogc.ows.exception.OwsExceptionReport
+request.handler.GenericOperationHandler;%0Aimport org.n52.iceland.request.handler.OperationHandlerKey;%0Aimport org.n52.javaps.engine.Engine
 ;%0Aim
@@ -1213,16 +1213,78 @@
 sValue;%0A
+import org.n52.shetland.ogc.ows.exception.OwsExceptionReport;%0A
 import o
@@ -1424,169 +1424,8 @@
 ts;%0A
-import org.n52.iceland.request.handler.GenericOperationHandler;%0Aimport org.n52.iceland.request.handler.OperationHandlerKey;%0Aimport org.n52.javaps.engine.Engine;%0A
 impo
@@ -2220,16 +2220,202 @@
 ffering%3E
+ offerings;%0A%0A        if (request.isAll()) %7B%0A            offerings = getEngine().getProcessDescriptions().stream().map(ProcessOffering::new).collect(toSet());%0A        %7D else %7B%0A           
  offerin
@@ -2499,20 +2499,16 @@
 iption)%0A
-    
         
@@ -2602,16 +2602,26 @@
 oSet());
+%0A        %7D
 %0A%0A      

Handle ALL keyword correctly