/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 WARRANTIESOR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.aries.containers.docker.local.impl;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.aries.containers.Service;
import org.apache.aries.containers.ServiceConfig;

public class ServiceImpl implements Service {
    private final ServiceConfig config;
    private final List<ContainerImpl> containers;
    private final LocalDockerContainerFactory factory;

    public ServiceImpl(ServiceConfig config,
            LocalDockerContainerFactory factory,
            List<ContainerImpl> containers) {
        this.config = config;
        this.factory = factory;
        this.containers = new CopyOnWriteArrayList<>(containers);
    }

    @Override
    public void destroy() {
        setInstanceCount(0);
    }

    @Override
    public int getActualInstanceCount() {
        return containers.size(); // TODO obtain live
    }

    @Override
    public void setInstanceCount(int count) {
        try {
            int curSize = containers.size();
            if (count < curSize) {
                for (int i=0 ; i < curSize - count; i++) {
                    killContainer(containers.remove(0));
                }
            } else {
                // TODO implement scaling up
            }
        } catch (Exception e) {
            LocalDockerContainerFactory.LOG.error("Problem changing instance count of service {} to {}",
                    config.getServiceName(), count, e);
        }
    }

    private void killContainer(ContainerImpl container) throws Exception {
        factory.destroyDockerContainer(container.getID(), true);
    }

    public void killAndReplaceContainer(ContainerImpl containerImpl) {
        // TODO implement
    }
}
