// Copyright (C) 2018 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.

export type ControllerAny = Controller</* StateType=*/ any>;

export interface ControllerFactory<ConstructorArgs> {
  new(args: ConstructorArgs): ControllerAny;
}

interface ControllerInitializer<ConstructorArgs> {
  id: string;
  factory: ControllerFactory<ConstructorArgs>;
  args: ConstructorArgs;
}

export type ControllerInitializerAny = ControllerInitializer<any>;

export function Child<ConstructorArgs>(
    id: string,
    factory: ControllerFactory<ConstructorArgs>,
    args: ConstructorArgs): ControllerInitializer<ConstructorArgs> {
  return {id, factory, args};
}

export type Children = ControllerInitializerAny[];

export abstract class Controller<StateType> {
  // This is about the local FSM state, has nothing to do with the global
  // app state.
  private _stateChanged = false;
  private _inRunner = false;
  private _state: StateType;
  private _children = new Map<string, ControllerAny>();

  constructor(initialState: StateType) {
    this._state = initialState;
  }

  abstract run(): Children|void;
  onDestroy(): void {}

  // Invokes the current controller subtree, recursing into children.
  // While doing so handles lifecycle of child controllers.
  // This method should be called only by the runControllers() method in
  // globals.ts. Exposed publicly for testing.
  invoke(): boolean {
    if (this._inRunner) throw new Error('Reentrancy in Controller');
    this._stateChanged = false;
    this._inRunner = true;
    const resArray = this.run();
    let triggerAnotherRun = this._stateChanged;
    this._stateChanged = false;

    const nextChildren = new Map<string, ControllerInitializerAny>();
    if (resArray !== undefined) {
      for (const childConfig of resArray) {
        if (nextChildren.has(childConfig.id)) {
          throw new Error(`Duplicate children controller ${childConfig.id}`);
        }
        nextChildren.set(childConfig.id, childConfig);
      }
    }
    const dtors = new Array<(() => void)>();
    const runners = new Array<(() => boolean)>();
    for (const key of this._children.keys()) {
      if (nextChildren.has(key)) continue;
      const instance = this._children.get(key)!;
      this._children.delete(key);
      dtors.push(() => instance.onDestroy());
    }
    for (const nextChild of nextChildren.values()) {
      if (!this._children.has(nextChild.id)) {
        const instance = new nextChild.factory(nextChild.args);
        this._children.set(nextChild.id, instance);
      }
      const instance = this._children.get(nextChild.id)!;
      runners.push(() => instance.invoke());
    }

    for (const dtor of dtors) dtor();  // Invoke all onDestroy()s.

    // Invoke all runner()s.
    for (const runner of runners) {
      const recursiveRes = runner();
      triggerAnotherRun = triggerAnotherRun || recursiveRes;
    }

    this._inRunner = false;
    return triggerAnotherRun;
  }

  setState(state: StateType) {
    if (!this._inRunner) {
      throw new Error('Cannot setState() outside of the run() method');
    }
    this._stateChanged = state !== this._state;
    this._state = state;
  }

  get state(): StateType {
    return this._state;
  }
}
