/*
 * 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.kafka.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class LoggingSignalHandler {

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

    private static final List<String> SIGNALS = Arrays.asList("TERM", "INT", "HUP");

    private final Constructor<?> signalConstructor;
    private final Class<?> signalHandlerClass;
    private final Class<?> signalClass;
    private final Method signalHandleMethod;
    private final Method signalGetNameMethod;
    private final Method signalHandlerHandleMethod;

    /**
     * Create an instance of this class.
     *
     * @throws ReflectiveOperationException if the underlying API has changed in an incompatible manner.
     */
    public LoggingSignalHandler() throws ReflectiveOperationException {
        signalClass = Class.forName("sun.misc.Signal");
        signalConstructor = signalClass.getConstructor(String.class);
        signalHandlerClass = Class.forName("sun.misc.SignalHandler");
        signalHandlerHandleMethod = signalHandlerClass.getMethod("handle", signalClass);
        signalHandleMethod = signalClass.getMethod("handle", signalClass, signalHandlerClass);
        signalGetNameMethod = signalClass.getMethod("getName");
    }

    /**
     * Register signal handler to log termination due to SIGTERM, SIGHUP and SIGINT (control-c). This method
     * does not currently work on Windows.
     *
     * @implNote sun.misc.Signal and sun.misc.SignalHandler are described as "not encapsulated" in
     * http://openjdk.java.net/jeps/260. However, they are not available in the compile classpath if the `--release`
     * flag is used. As a workaround, we rely on reflection.
     */
    public void register() throws ReflectiveOperationException {
        Map<String, Object> jvmSignalHandlers = new ConcurrentHashMap<>();

        for (String signal : SIGNALS) {
            register(signal, jvmSignalHandlers);
        }
        log.info("Registered signal handlers for " + String.join(", ", SIGNALS));
    }

    private Object createSignalHandler(final Map<String, Object> jvmSignalHandlers) {
        InvocationHandler invocationHandler = new InvocationHandler() {

            private String getName(Object signal) throws ReflectiveOperationException {
                return (String) signalGetNameMethod.invoke(signal);
            }

            private void handle(Object signalHandler, Object signal) throws ReflectiveOperationException {
                signalHandlerHandleMethod.invoke(signalHandler, signal);
            }

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object signal = args[0];
                log.info("Terminating process due to signal {}", signal);
                Object handler = jvmSignalHandlers.get(getName(signal));
                if (handler != null)
                    handle(handler, signal);
                return null;
            }
        };
        return Proxy.newProxyInstance(Utils.getContextOrKafkaClassLoader(), new Class[] {signalHandlerClass},
                invocationHandler);
    }

    private void register(String signalName, final Map<String, Object> jvmSignalHandlers) throws ReflectiveOperationException {
        Object signal = signalConstructor.newInstance(signalName);
        Object signalHandler = createSignalHandler(jvmSignalHandlers);
        Object oldHandler = signalHandleMethod.invoke(null, signal, signalHandler);
        if (oldHandler != null)
            jvmSignalHandlers.put(signalName, oldHandler);
    }
}
