/*
 * Copyright 2011 Google Inc.
 *
 * Licensed 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 com.google.ipc.invalidation.ticl.android2;

import com.google.ipc.invalidation.external.client.InvalidationClient;
import com.google.ipc.invalidation.external.client.InvalidationListener;
import com.google.ipc.invalidation.external.client.InvalidationListener.RegistrationState;
import com.google.ipc.invalidation.external.client.android.service.AndroidLogger;
import com.google.ipc.invalidation.external.client.types.AckHandle;
import com.google.ipc.invalidation.external.client.types.ErrorInfo;
import com.google.ipc.invalidation.ticl.ProtoWrapperConverter;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall.ErrorUpcall;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall.InvalidateUpcall;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall.RegistrationFailureUpcall;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall.RegistrationStatusUpcall;
import com.google.ipc.invalidation.ticl.proto.AndroidService.ListenerUpcall.ReissueRegistrationsUpcall;
import com.google.ipc.invalidation.util.ProtoWrapper.ValidationException;

import android.content.Context;
import android.content.Intent;

import java.util.Arrays;


/**
 * Routes intents to the appropriate methods in {@link InvalidationListener}. Typically, an instance
 * of the mapper should be created in {@code IntentService#onCreate} and the {@link #handleIntent}
 * method called in {@code IntentService#onHandleIntent}.
 *
 */
public final class AndroidInvalidationListenerIntentMapper {

  /** The logger. */
  private final AndroidLogger logger = AndroidLogger.forPrefix("");

  /** Client passed to the listener (supports downcalls). */
  public final InvalidationClient client;

  /** Listener to which intents are routed. */
  private final InvalidationListener listener;

  /**
   * Initializes
   *
   * @param listener the listener to which intents should be routed
   * @param context the context used by the listener to issue downcalls to the TICL
   */
  public AndroidInvalidationListenerIntentMapper(InvalidationListener listener, Context context) {
    client = new AndroidInvalidationClientStub(context, logger);
    this.listener = listener;
  }

  /**
   * Handles a listener upcall by decoding the protocol buffer in {@code intent} and dispatching
   * to the appropriate method on the {@link #listener}.
   */
  public void handleIntent(Intent intent) {
    // TODO: use wakelocks

    // Unmarshall the arguments from the Intent and make the appropriate call on the listener.
    ListenerUpcall upcall = tryParseIntent(intent);
    if (upcall == null) {
      return;
    }

    if (upcall.hasReady()) {
      listener.ready(client);
    } else if (upcall.getNullableInvalidate() != null) {
      // Handle all invalidation-related upcalls on a common path, since they require creating
      // an AckHandleP.
      onInvalidateUpcall(upcall.getNullableInvalidate(), listener);
    } else if (upcall.getNullableRegistrationStatus() != null) {
      RegistrationStatusUpcall regStatus = upcall.getNullableRegistrationStatus();
      listener.informRegistrationStatus(client,
          ProtoWrapperConverter.convertFromObjectIdProto(regStatus.getObjectId()),
          regStatus.getIsRegistered() ?
              RegistrationState.REGISTERED : RegistrationState.UNREGISTERED);
    } else if (upcall.getNullableRegistrationFailure() != null) {
      RegistrationFailureUpcall failure = upcall.getNullableRegistrationFailure();
      listener.informRegistrationFailure(client,
          ProtoWrapperConverter.convertFromObjectIdProto(failure.getObjectId()),
          failure.getTransient(),
          failure.getMessage());
    } else if (upcall.getNullableReissueRegistrations() != null) {
      ReissueRegistrationsUpcall reissueRegs = upcall.getNullableReissueRegistrations();
      listener.reissueRegistrations(client, reissueRegs.getPrefix().getByteArray(),
          reissueRegs.getLength());
    } else if (upcall.getNullableError() != null) {
      ErrorUpcall error = upcall.getNullableError();
      ErrorInfo errorInfo = ErrorInfo.newInstance(error.getErrorCode(), error.getIsTransient(),
          error.getErrorMessage(), null);
      listener.informError(client, errorInfo);
    } else {
      logger.warning("Dropping listener Intent with unknown call: %s", upcall);
    }
  }

  /**
   * Handles an invalidation-related listener {@code upcall} by dispatching to the appropriate
   * method on an instance of {@link InvalidationListener}.
   */
  private void onInvalidateUpcall(InvalidateUpcall invalidate, InvalidationListener listener) {
    AckHandle ackHandle = AckHandle.newInstance(invalidate.getAckHandle().getByteArray());
    if (invalidate.getNullableInvalidation() != null) {
      listener.invalidate(client,
          ProtoWrapperConverter.convertFromInvalidationProto(invalidate.getNullableInvalidation()),
          ackHandle);
    } else if (invalidate.hasInvalidateAll()) {
      listener.invalidateAll(client, ackHandle);
    } else if (invalidate.getNullableInvalidateUnknown() != null) {
      listener.invalidateUnknownVersion(client,
          ProtoWrapperConverter.convertFromObjectIdProto(invalidate.getNullableInvalidateUnknown()),
          ackHandle);
    } else {
      throw new RuntimeException("Invalid invalidate upcall: " + invalidate);
    }
  }

  /**
   * Returns a valid {@link ListenerUpcall} from {@code intent}, or {@code null} if one
   * could not be parsed.
   */
  private ListenerUpcall tryParseIntent(Intent intent) {
    if (intent == null) {
      return null;
    }
    byte[] upcallBytes = intent.getByteArrayExtra(ProtocolIntents.LISTENER_UPCALL_KEY);
    if (upcallBytes == null) {
      return null;
    }
    try {
      ListenerUpcall upcall = ListenerUpcall.parseFrom(upcallBytes);
      return upcall;
    } catch (ValidationException exception) {
      logger.severe("Could not parse listener upcall from %s", Arrays.toString(upcallBytes));
      return null;
    }
  }
}
