// Copyright 2018 The Feed Authors.
//
// 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.android.libraries.feed.feedstore;

import com.google.android.libraries.feed.api.common.ActionPropertiesWithId;
import com.google.android.libraries.feed.api.common.PayloadWithId;
import com.google.android.libraries.feed.api.common.SemanticPropertiesWithId;
import com.google.android.libraries.feed.api.common.ThreadUtils;
import com.google.android.libraries.feed.api.lifecycle.Resettable;
import com.google.android.libraries.feed.api.store.ActionPropertiesMutation;
import com.google.android.libraries.feed.api.store.ContentMutation;
import com.google.android.libraries.feed.api.store.LocalActionMutation;
import com.google.android.libraries.feed.api.store.SemanticPropertiesMutation;
import com.google.android.libraries.feed.api.store.SessionMutation;
import com.google.android.libraries.feed.api.store.Store;
import com.google.android.libraries.feed.api.store.StoreListener;
import com.google.android.libraries.feed.api.store.UploadableActionMutation;
import com.google.android.libraries.feed.common.Result;
import com.google.android.libraries.feed.common.concurrent.MainThreadRunner;
import com.google.android.libraries.feed.common.concurrent.TaskQueue;
import com.google.android.libraries.feed.common.concurrent.TaskQueue.TaskType;
import com.google.android.libraries.feed.common.feedobservable.FeedObservable;
import com.google.android.libraries.feed.common.functional.Supplier;
import com.google.android.libraries.feed.common.logging.Logger;
import com.google.android.libraries.feed.common.protoextensions.FeedExtensionRegistry;
import com.google.android.libraries.feed.common.time.Clock;
import com.google.android.libraries.feed.common.time.TimingUtils;
import com.google.android.libraries.feed.common.time.TimingUtils.ElapsedTimeTracker;
import com.google.android.libraries.feed.feedapplifecyclelistener.FeedLifecycleListener;
import com.google.android.libraries.feed.feedstore.internal.ClearableStore;
import com.google.android.libraries.feed.feedstore.internal.EphemeralFeedStore;
import com.google.android.libraries.feed.feedstore.internal.FeedStoreHelper;
import com.google.android.libraries.feed.feedstore.internal.PersistentFeedStore;
import com.google.android.libraries.feed.host.logging.BasicLoggingApi;
import com.google.android.libraries.feed.host.logging.InternalFeedError;
import com.google.android.libraries.feed.host.storage.CommitResult;
import com.google.android.libraries.feed.host.storage.ContentStorageDirect;
import com.google.android.libraries.feed.host.storage.JournalStorageDirect;
import com.google.protobuf.ByteString;
import com.google.search.now.feed.client.StreamDataProto.StreamLocalAction;
import com.google.search.now.feed.client.StreamDataProto.StreamSharedState;
import com.google.search.now.feed.client.StreamDataProto.StreamStructure;
import com.google.search.now.feed.client.StreamDataProto.StreamUploadableAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * {@link Store} implementation that delegates between {@link PersistentFeedStore} and {@link
 * EphemeralFeedStore}.
 *
 * <p>TODO: We need to design the StoreListener support correctly. For the switch to
 * ephemeral mode, the Observers are called from here. If we ever have events which are raised by
 * one of the delegates, we need to make sure the registered observers are called correctly,
 * independent of what delegate is actually running. The delegates currently throw a
 * IllegalStateException if the register/unregister methods are called.
 */
public class FeedStore extends FeedObservable<StoreListener>
    implements Store, Resettable, FeedLifecycleListener {
  private static final String TAG = "FeedStore";

  // Permanent reference to the persistent store (used for setting off cleanup)
  private final PersistentFeedStore persistentStore;
  private final MainThreadRunner mainThreadRunner;
  // The current store
  private ClearableStore delegate;

  private final TaskQueue taskQueue;

  // Needed for switching to ephemeral mode
  private final FeedStoreHelper storeHelper = new FeedStoreHelper();
  private final BasicLoggingApi basicLoggingApi;
  private final Clock clock;
  private final TimingUtils timingUtils;
  private final ThreadUtils threadUtils;

  private boolean isEphemeralMode = false;

  public FeedStore(
      TimingUtils timingUtils,
      FeedExtensionRegistry extensionRegistry,
      ContentStorageDirect contentStorage,
      JournalStorageDirect journalStorage,
      ThreadUtils threadUtils,
      TaskQueue taskQueue,
      Clock clock,
      BasicLoggingApi basicLoggingApi,
      MainThreadRunner mainThreadRunner) {
    this.taskQueue = taskQueue;
    this.clock = clock;
    this.timingUtils = timingUtils;
    this.threadUtils = threadUtils;
    this.basicLoggingApi = basicLoggingApi;
    this.mainThreadRunner = mainThreadRunner;

    this.persistentStore =
        new PersistentFeedStore(
            this.timingUtils,
            extensionRegistry,
            contentStorage,
            journalStorage,
            threadUtils,
            this.clock,
            this.storeHelper);
    delegate = persistentStore;
  }

  @Override
  public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
    return delegate.getPayloads(contentIds);
  }

  @Override
  public Result<List<StreamSharedState>> getSharedStates() {
    return delegate.getSharedStates();
  }

  @Override
  public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
    return delegate.getStreamStructures(sessionId);
  }

  @Override
  public Result<List<String>> getAllSessions() {
    return delegate.getAllSessions();
  }

  @Override
  public Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds) {
    return delegate.getSemanticProperties(contentIds);
  }

  @Override
  public Result<List<ActionPropertiesWithId>> getActionProperties(List<String> contentIds) {
    return delegate.getActionProperties(contentIds);
  }

  @Override
  public Result<List<StreamLocalAction>> getAllDismissLocalActions() {
    return delegate.getAllDismissLocalActions();
  }

  @Override
  public Result<Set<StreamUploadableAction>> getAllUploadableActions() {
    return delegate.getAllUploadableActions();
  }

  @Override
  public Result<String> createNewSession() {
    return delegate.createNewSession();
  }

  @Override
  public void removeSession(String sessionId) {
    delegate.removeSession(sessionId);
  }

  @Override
  public void clearHead() {
    delegate.clearHead();
  }

  @Override
  public ContentMutation editContent() {
    return delegate.editContent();
  }

  @Override
  public SessionMutation editSession(String sessionId) {
    return delegate.editSession(sessionId);
  }

  @Override
  public SemanticPropertiesMutation editSemanticProperties() {
    return delegate.editSemanticProperties();
  }

  @Override
  public ActionPropertiesMutation editActionProperties() {
    return delegate.editActionProperties();
  }

  @Override
  public LocalActionMutation editLocalActions() {
    return delegate.editLocalActions();
  }

  @Override
  public UploadableActionMutation editUploadableActions() {
    return delegate.editUploadableActions();
  }

  @Override
  public Runnable triggerContentGc(
      Set<String> reservedContentIds, Supplier<Set<String>> accessibleContent) {
    return delegate.triggerContentGc(reservedContentIds, accessibleContent);
  }

  @Override
  public Runnable triggerLocalActionGc(
      List<StreamLocalAction> actions, List<String> validContentIds) {
    return delegate.triggerLocalActionGc(actions, validContentIds);
  }

  @Override
  public boolean isEphemeralMode() {
    return isEphemeralMode;
  }

  @Override
  public void switchToEphemeralMode() {
    // This should be called on a background thread because it's called during error handling.
    threadUtils.checkNotMainThread();
    if (!isEphemeralMode) {
      persistentStore.switchToEphemeralMode();
      delegate = new EphemeralFeedStore(clock, timingUtils, storeHelper);

      taskQueue.execute(
          "clearPersistentStoreTask",
          TaskType.BACKGROUND,
          () -> {
            ElapsedTimeTracker tracker = timingUtils.getElapsedTimeTracker(TAG);
            // Try to just wipe content + sessions
            boolean clearSuccess = persistentStore.clearNonActionContent();
            // If that fails, wipe everything.
            if (!clearSuccess) {
              persistentStore.clearAll();
            }
            tracker.stop("clearPersistentStore", "completed");
          });

      isEphemeralMode = true;
      synchronized (observers) {
        for (StoreListener listener : observers) {
          listener.onSwitchToEphemeralMode();
        }
      }
      mainThreadRunner.execute(
          "log ephemeral switch",
          () -> basicLoggingApi.onInternalError(InternalFeedError.SWITCH_TO_EPHEMERAL));
    }
  }

  @Override
  public void reset() {
    persistentStore.clearNonActionContent();
  }

  @Override
  public void onLifecycleEvent(@LifecycleEvent String event) {
    if (LifecycleEvent.ENTER_BACKGROUND.equals(event) && isEphemeralMode) {
      taskQueue.execute("dumpEphemeralActions", TaskType.BACKGROUND, this::dumpEphemeralActions);
    }
  }

  private void dumpEphemeralActions() {
    // Get all action-related content (actions + semantic data)
    Result<List<StreamLocalAction>> dismissActionsResult = delegate.getAllDismissLocalActions();
    if (!dismissActionsResult.isSuccessful()) {
      Logger.e(TAG, "Error retrieving actions when trying to dump ephemeral actions.");
      return;
    }
    List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
    LocalActionMutation localActionMutation = persistentStore.editLocalActions();
    List<String> dismissActionContentIds = new ArrayList<>(dismissActions.size());
    for (StreamLocalAction dismiss : dismissActions) {
      dismissActionContentIds.add(dismiss.getFeatureContentId());
      localActionMutation.add(dismiss.getAction(), dismiss.getFeatureContentId());
    }
    Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
        delegate.getSemanticProperties(dismissActionContentIds);
    if (!semanticPropertiesResult.isSuccessful()) {
      Logger.e(TAG, "Error retrieving semantic properties when trying to dump ephemeral actions.");
      return;
    }
    SemanticPropertiesMutation semanticPropertiesMutation =
        persistentStore.editSemanticProperties();
    for (SemanticPropertiesWithId semanticProperties : semanticPropertiesResult.getValue()) {
      semanticPropertiesMutation.add(
          semanticProperties.contentId, ByteString.copyFrom(semanticProperties.semanticData));
    }

    // Attempt to write action-related content to persistent storage
    CommitResult commitResult = localActionMutation.commit();
    if (commitResult != CommitResult.SUCCESS) {
      Logger.e(TAG, "Error writing actions to persistent store when dumping ephemeral actions.");
      return;
    }
    commitResult = semanticPropertiesMutation.commit();
    if (commitResult != CommitResult.SUCCESS) {
      Logger.e(
          TAG,
          "Error writing semantic properties to persistent store when dumping ephemeral actions.");
    }
  }
}
