// Copyright (C) 2023 The Android Open Source Project
//
// 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.

import produce, {Draft} from 'immer';

import {Disposable} from './disposable';
import {getPath, Path, setPath} from './object_utils';

export type Migrate<T> = (init: unknown) => T;
export type Edit<T> = (draft: Draft<T>) => void;
export type Callback<T> = (store: Store<T>, previous: T) => void;

/**
 * Create a new root-level store.
 *
 * @template T The type of this store's state.
 * @param {T} initialState Initial state of the store.
 * @return {Store<T>} The newly created store.
 */
export function createStore<T>(initialState: T): Store<T> {
  return new RootStore<T>(initialState);
}

export interface Store<T> extends Disposable {
  /**
   * Access the immutable state of this store.
   */
  get state(): T;

  /**
   * Mutate the store's state.
   *
   * @param {Edit<T> | Edit<T>[]} edits The edit (or edits) to the store.
   */
  edit(edits: Edit<T> | Edit<T>[]): void;

  /**
   * Create a sub-store from a subtree of the state from this store.
   *
   * The returned store looks and feels like a regular store but acts only on a
   * specific subtree of its parent store. Reads are writes are channelled
   * through to the parent store via the |migrate| function.
   *
   * |migrate| is called the first time we access our sub-store's state and
   * whenever the subtree changes in the root store.
   * This migrate function takes the state of the subtree from the sub-store's
   * parent store which has unknown type and is responsible for returning a
   * value whose type matches that of the sub-store's state.
   *
   * Sub-stores may be created over the top of subtrees which are not yet fully
   * defined. The state is written to the parent store on first edit. The
   * sub-store can also deal with the underlying subtree becoming undefined
   * again at some point in the future, and so is robust to unpredictable
   * changes to the root store.
   *
   * @template U The type of the sub-store's state.
   * @param path The path to the subtree this sub-store is based on.
   * @example
   * // Given a store whose state takes the form:
   * {
   *   foo: {
   *     bar: [ {baz: 123}, {baz: 42} ],
   *   },
   * }
   *
   * // A sub-store crated on path: ['foo','bar', 1] would only see the state:
   * {
   *   baz: 42,
   * }
   * @param migrate A function used to migrate from the parent store's subtree
   * to the sub-store's state.
   * @example
   * interface RootState {dict: {[key: string]: unknown}};
   * interface SubState {foo: string};
   *
   * const store = createStore({dict: {}});
   * const migrate = (init: unknown) => (init ?? {foo: 'bar'}) as SubState;
   * const subStore = store.createSubStore(store, ['dict', 'foo'], migrate);
   * // |dict['foo']| will be created the first time we edit our sub-store.
   * @warning Migration functions should properly validate the incoming state.
   * Blindly using type assertions can lead to instability.
   * @returns {Store<U>} The newly created sub-store.
   */
  createSubStore<U>(path: Path, migrate: Migrate<U>): Store<U>;

  /**
   * Subscribe for notifications when any edits are made to this store.
   *
   * @param callback The function to be called.
   * @returns {Disposable} When this is disposed, the subscription is removed.
   */
  subscribe(callback: Callback<T>): Disposable;
}

/**
 * This class implements a standalone store (i.e. one that does not depend on a
 * subtree of another store).
 * @template T The type of the store's state.
 */
class RootStore<T> implements Store<T> {
  private internalState: T;
  private subscriptions = new Set<Callback<T>>();

  constructor(initialState: T) {
    // Run initial state through immer to take advantage of auto-freezing
    this.internalState = produce(initialState, () => {});
  }

  get state() {
    return this.internalState;
  }

  edit(edit: Edit<T> | Edit<T>[]): void {
    if (Array.isArray(edit)) {
      this.applyEdits(edit);
    } else {
      this.applyEdits([edit]);
    }
  }

  private applyEdits(edits: Edit<T>[]): void {
    const originalState = this.internalState;

    const newState = edits.reduce((state, edit) => {
      return produce(state, edit);
    }, originalState);

    if (originalState !== newState) {
      this.internalState = newState;

      // Notify subscribers
      this.subscriptions.forEach((sub) => {
        sub(this, originalState);
      });
    }
  }

  createSubStore<U>(path: Path, migrate: Migrate<U>): Store<U> {
    return new SubStore(this, path, migrate);
  }

  subscribe(callback: Callback<T>): Disposable {
    this.subscriptions.add(callback);
    return {
      dispose: () => {
        this.subscriptions.delete(callback);
      },
    };
  }

  dispose(): void {
    // No-op
  }
}

/**
 * This class implements a sub-store, one that is based on a subtree of another
 * store. The parent store can be a root level store or another sub-store.
 *
 * This particular implementation of a sub-tree implements a write-through cache
 * style implementation. The sub-store's state is cached internally and all
 * edits are written through to the parent store as with a best-effort approach.
 * If the subtree does not exist in the parent store, an error is printed to
 * the console but the operation is still treated as a success.
 *
 * @template T The type of the sub-store's state.
 * @template ParentT The type of the parent store's state.
 */
class SubStore<T, ParentT> implements Store<T> {
  private parentState: unknown;
  private cachedState: T;
  private parentStoreSubscription: Disposable;
  private subscriptions = new Set<Callback<T>>();

  constructor(
    private readonly parentStore: Store<ParentT>,
    private readonly path: Path,
    private readonly migrate: (init: unknown) => T,
  ) {
    this.parentState = getPath<unknown>(this.parentStore.state, this.path);

    // Run initial state through immer to take advantage of auto-freezing
    this.cachedState = produce(migrate(this.parentState), () => {});

    // Subscribe to parent store changes.
    this.parentStoreSubscription = this.parentStore.subscribe(() => {
      const newRootState = getPath<unknown>(this.parentStore.state, this.path);
      if (newRootState !== this.parentState) {
        this.subscriptions.forEach((callback) => {
          callback(this, this.cachedState);
        });
      }
    });
  }

  get state(): T {
    const parentState = getPath<unknown>(this.parentStore.state, this.path);
    if (this.parentState === parentState) {
      return this.cachedState;
    } else {
      this.parentState = parentState;
      return (this.cachedState = produce(this.cachedState, () => {
        return this.migrate(parentState);
      }));
    }
  }

  edit(edit: Edit<T> | Edit<T>[]): void {
    if (Array.isArray(edit)) {
      this.applyEdits(edit);
    } else {
      this.applyEdits([edit]);
    }
  }

  private applyEdits(edits: Edit<T>[]): void {
    const originalState = this.cachedState;

    const newState = edits.reduce((state, edit) => {
      return produce(state, edit);
    }, originalState);

    if (originalState !== newState) {
      this.parentState = newState;
      try {
        this.parentStore.edit((draft) => {
          setPath(draft, this.path, newState);
        });
      } catch (error) {
        if (error instanceof TypeError) {
          console.warn('Failed to update parent store at ', this.path);
        } else {
          throw error;
        }
      }

      this.cachedState = newState;

      this.subscriptions.forEach((sub) => {
        sub(this, originalState);
      });
    }
  }

  createSubStore<SubtreeState>(
    path: Path,
    migrate: Migrate<SubtreeState>,
  ): Store<SubtreeState> {
    return new SubStore(this, path, migrate);
  }

  subscribe(callback: Callback<T>): Disposable {
    this.subscriptions.add(callback);
    return {
      dispose: () => {
        this.subscriptions.delete(callback);
      },
    };
  }

  dispose(): void {
    this.parentStoreSubscription.dispose();
  }
}
