/*
 * Copyright (c) 2019 the Eclipse Milo Authors
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 */

package org.eclipse.milo.opcua.sdk.client.methods;

import java.util.concurrent.CompletableFuture;

import org.eclipse.milo.opcua.sdk.client.api.UaClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.eclipse.milo.opcua.stack.core.types.structured.CallMethodRequest;

public abstract class AbstractUaMethod {

    private final UaClient client;
    private final NodeId objectId;
    private final NodeId methodId;

    public AbstractUaMethod(UaClient client, NodeId objectId, NodeId methodId) {
        this.client = client;
        this.objectId = objectId;
        this.methodId = methodId;
    }

    public CompletableFuture<Variant[]> invoke(Variant[] inputArguments) {
        CallMethodRequest request = new CallMethodRequest(
            objectId,
            methodId,
            inputArguments
        );

        return client.call(request).thenCompose(result -> {
            StatusCode statusCode = result.getStatusCode();

            if (statusCode.isGood()) {
                Variant[] outputArguments = result.getOutputArguments();

                return CompletableFuture.completedFuture(outputArguments);
            } else {
                UaMethodException ex = new UaMethodException(
                    statusCode,
                    result.getInputArgumentResults(),
                    result.getInputArgumentDiagnosticInfos()
                );

                CompletableFuture<Variant[]> f = new CompletableFuture<>();
                f.completeExceptionally(ex);
                return f;
            }
        });
    }

}
