/*
 *******************************************************************************
 * Copyright (c) 2018 Contributors to the Eclipse Foundation
 * 
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
*/package org.eclipse.openk.core.controller;

import org.apache.log4j.Logger;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.openk.api.VersionInfo;
import org.eclipse.openk.api.ServiceDistributionCluster;
import org.eclipse.openk.core.common.Globals;
import org.eclipse.openk.core.communication.RestServiceWrapper;
import org.eclipse.openk.core.exceptions.HttpStatusException;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class CentralController {
    private static final Logger logger = Logger.getLogger(CentralController.class);

    public ServiceDistributionCluster readServerDistribution(String cluster) throws HttpStatusException {
        ServiceDistributionCluster[] dcs = ServicesConfigCache.getInstance().getCache();

        for (ServiceDistributionCluster item : dcs) {
            if (item.getClustername().equalsIgnoreCase(cluster) && item.isActive()) {
                return removeInactiveItems(item);
            }
        }
        logger.error("There is no cluster name equals with " + cluster + " or the cluster is not active.");
        throw new HttpStatusException(HttpStatus.NOT_FOUND_404);
    }

    public VersionInfo getVersionInfo(String version ) {
        VersionInfo vi = new VersionInfo();
        vi.setBackendVersion( version );
        return vi;
    }


    protected RestServiceWrapper createRestServiceWrapper( boolean isHttps ) {
        return new RestServiceWrapper(isHttps);
    }

    public String getServiceHealthState(String clustername, String servicename) throws HttpStatusException {

        ServiceDistributionCluster.ServiceDistribution dist = findDistribution(clustername, servicename);
        RestServiceWrapper w = createRestServiceWrapper(false );
        StringBuilder url = new StringBuilder();
        url.append(dist.getProtocol() + "://" + dist.getHost() + ":"
                + dist.getPortHealth());

        if( dist.getHealthUrlPath() != null ) {
            url.append(dist.getUrlPath());
        }
        url.append("/" + Globals.HEALTH_CHECK_ADD_PATH );

        return w.performGetRequest(url.toString());
    }

    private ServiceDistributionCluster.ServiceDistribution findDistribution(String clustername,
                                                                            String servicename) throws HttpStatusException {
        ServiceDistributionCluster cluster = getCluster(ServicesConfigCache.getInstance().getCache(), clustername);

        Optional<ServiceDistributionCluster.ServiceDistribution> dist = Arrays.stream(cluster.getDistributions())
                .filter(e -> e.isActive() && e.getName().equals(servicename))
                .findFirst();

        if(dist.isPresent()) {
            return dist.get();
        }
        else {
            throw new HttpStatusException(HttpStatus.NOT_FOUND_404);
        }
    }

    private ServiceDistributionCluster getCluster(ServiceDistributionCluster[] clusterArray, String clustername) throws HttpStatusException {
        List<ServiceDistributionCluster> clusterList = Arrays.asList(clusterArray);
        Optional<ServiceDistributionCluster> ret = clusterList.stream()
                .filter(c -> c.getClustername().equals(clustername)).findFirst();

        if (ret.isPresent()) {
            return ret.get();
        } else {
            logger.info("Could not find a cluster with the name: " + clustername);
            throw new HttpStatusException(HttpStatus.NOT_FOUND_404);
        }
    }

    private ServiceDistributionCluster removeInactiveItems( ServiceDistributionCluster cluster ) {
        List<ServiceDistributionCluster.ServiceDistribution> dlist = Arrays.asList(cluster.getDistributions());
        dlist = dlist.stream().filter(ServiceDistributionCluster.ServiceDistribution::isActive).collect(Collectors.toList());
        ServiceDistributionCluster.ServiceDistribution[] distArr
                = new ServiceDistributionCluster.ServiceDistribution[dlist.size()];
        cluster.setDistributions(dlist.toArray(distArr));
        return cluster;
    }


}
