/*
 * 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.reef.wake.impl;

import org.apache.reef.wake.MultiObserver;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * The MultiObserverImpl class uses reflection to discover which onNext()
 * event processing methods are defined and then map events to them.
 * @param <TSubCls> The subclass derived from MultiObserverImpl.
 */
public abstract class MultiObserverImpl<TSubCls> implements MultiObserver {
  private static final Logger LOG = Logger.getLogger(MultiObserverImpl.class.getName());
  private final Map<String, Method> methodMap = new HashMap<>();

  /**
   * Use reflection to discover all of the event processing methods in TSubCls
   * and setup a means to direct calls from the generic event onNext method defined
   * in the MultiObserver interface to specific concrete event onNext methods.
   */
  public MultiObserverImpl() {
    // Iterate across the methods and build a hash map of class names to reflection methods.
    for (final Method method : this.getClass().getMethods()) {
      if (method.getName().equals("onNext") && method.getDeclaringClass().equals(this.getClass())) {
        // This is an onNext method defined in TSubCls
        final Class<?>[] types = method.getParameterTypes();
        if (types.length == 2 && types[0].equals(Long.TYPE)) {
          methodMap.put(types[1].getName(), method);
        }
      }
    }
  }

  /**
   * Called when an event is received that does not have an onNext method definition
   * in TSubCls. Override in TSubClas to handle the error.
   * @param event A reference to an object which is an event not handled by TSubCls.
   * @param <TEvent> The type of the event being processed.
   */
  private <TEvent> void unimplemented(final long identifier, final TEvent event) {
    LOG.log(Level.INFO, "Unimplemented event: [{0}]: {1}",
        new String[]{String.valueOf(identifier), event.getClass().getName()});
  }

  /**
   * Generic event onNext method in the base interface which maps the call to a concrete
   * event onNext method in TSubCls if one exists otherwise unimplemented is invoked.
   * @param event An event of type TEvent which will be sent to TSubCls as appropriate.
   * @param <TEvent> The type of the event being processed.
   */
  @Override
  public <TEvent> void onNext(final long identifier, final TEvent event)
    throws IllegalAccessException, InvocationTargetException {

    // Get the reflection method for this call.
    final Method onNext = methodMap.get(event.getClass().getName());
    if (onNext != null) {
      // Process the event.
      onNext.invoke((TSubCls) this, identifier, event);
    } else {
      // Log the unprocessed event.
      unimplemented(identifier, event);
    }
  }
}
