/*
 * 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 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.apache.jackrabbit.oak.segment.standby.server;

import java.io.Closeable;
import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;

import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.segment.standby.jmx.StandbyStatusMBean;
import org.apache.jackrabbit.oak.segment.standby.store.CommunicationObserver;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StandbyServerSync implements StandbyStatusMBean, StateConsumer, StoreProvider, Closeable {

    private static final Logger log = LoggerFactory.getLogger(StandbyServer.class);

    private final FileStore fileStore;

    private final CommunicationObserver observer;

    private final int port;

    private final String[] allowedClientIPRanges;

    private final boolean secure;
    
    private final int blobChunkSize;

    private volatile String state;

    private final AtomicBoolean running = new AtomicBoolean(false);

    private StandbyServer server;

    public StandbyServerSync(final int port, final FileStore fileStore, final int blobChunkSize) {
        this(port, fileStore, blobChunkSize, null, false);
    }

    public StandbyServerSync(final int port, final FileStore fileStore, final int blobChunkSize, final boolean secure) {
        this(port, fileStore, blobChunkSize, null, secure);
    }

    public StandbyServerSync(final int port, final FileStore fileStore, final int blobChunkSize, final String[] allowedClientIPRanges) {
        this(port, fileStore, blobChunkSize, allowedClientIPRanges, false);
    }

    public StandbyServerSync(final int port, final FileStore fileStore, final int blobChunkSize, final String[] allowedClientIPRanges, final boolean secure) {
        this.port = port;
        this.fileStore = fileStore;
        this.blobChunkSize = blobChunkSize;
        this.allowedClientIPRanges = allowedClientIPRanges;
        this.secure = secure;
        this.observer = new CommunicationObserver("primary");

        final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();

        try {
            jmxServer.registerMBean(new StandardMBean(this, StandbyStatusMBean.class), new ObjectName(this.getMBeanName()));
        } catch (Exception e) {
            log.error("can't register standby status mbean", e);
        }
    }

    @Override
    public void consumeState(String state) {
        this.state = state;
    }

    @Override
    public FileStore provideStore() {
        return fileStore;
    }

    @Override
    public void start() {
        if (isRunning()) {
            return;
        }

        state = STATUS_STARTING;

        try {
            server = StandbyServer.builder(port, this, blobChunkSize)
                    .secure(secure)
                    .allowIPRanges(allowedClientIPRanges)
                    .withStateConsumer(this)
                    .withObserver(observer)
                    .build();
            server.start();

            state = STATUS_RUNNING;
            running.set(true);
        } catch (Exception e) {
            log.error("Server could not be started.", e);
            state = null;
            running.set(false);
        }
    }

    @Override
    public void stop() {
        if (server != null) {
            server.stop();
        }

        running.set(false);
        state = STATUS_STOPPED;
    }

    @Override
    public void close() {
        stop();
        state = STATUS_CLOSING;
        if (server != null) {
            server.close();
        }
        observer.unregister();
        final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
        try {
            jmxServer.unregisterMBean(new ObjectName(this.getMBeanName()));
        } catch (InstanceNotFoundException e) {
            // ignore
        } catch (Exception e) {
            log.error("can't unregister standby status mbean", e);
        }

        state = STATUS_CLOSED;
    }

    @NotNull
    @Override
    public String getMode() {
        return "primary";
    }

    @Override
    public String getStatus() {
        return state == null ? STATUS_INITIALIZING : state;
    }

    @Override
    public boolean isRunning() {
        return running.get();
    }

    public String getMBeanName() {
        return StandbyStatusMBean.JMX_NAME + ",id=" + this.port;
    }

}
