// 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 {Draft} from 'immer';

import {createStore} from './store';
import {exists} from './utils';

interface Bar {
  value: number;
}

interface Foo {
  counter: number;
  nested: Bar;
}

function migrateFoo(init: unknown): Foo {
  const migrated: Foo = {
    counter: 123,
    nested: {
      value: 456,
    },
  };
  if (exists(init) && typeof init === 'object') {
    if ('counter' in init && typeof init.counter === 'number') {
      migrated.counter = init.counter;
    }
    if ('nested' in init && typeof init.nested === 'object' && init.nested) {
      if ('value' in init.nested && typeof init.nested.value === 'number') {
        migrated.nested.value = init.nested.value;
      }
    }
  }

  console.log('migrating', init);

  return migrated;
}

interface State {
  foo: Foo;
}

const initialState: State = {
  foo: {
    counter: 0,
    nested: {
      value: 42,
    },
  },
};

describe('root store', () => {
  test('edit', () => {
    const store = createStore(initialState);
    store.edit((draft) => {
      draft.foo.counter += 123;
    });

    expect(store.state).toEqual({
      foo: {
        counter: 123,
        nested: {
          value: 42,
        },
      },
    });
  });

  test('state [in]equality', () => {
    const store = createStore(initialState);
    store.edit((draft) => {
      draft.foo.counter = 88;
    });
    expect(store.state).not.toBe(initialState);
    expect(store.state.foo).not.toBe(initialState.foo);
    expect(store.state.foo.nested).toBe(initialState.foo.nested);
  });

  it('can take multiple edits at once', () => {
    const store = createStore(initialState);
    const callback = jest.fn();

    store.subscribe(callback);

    store.edit([
      (draft) => {
        draft.foo.counter += 10;
      },
      (draft) => {
        draft.foo.counter += 10;
      },
    ]);

    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(store, initialState);
    expect(store.state).toEqual({
      foo: {
        counter: 20,
        nested: {
          value: 42,
        },
      },
    });
  });

  it('can support a huge number of edits', () => {
    const store = createStore(initialState);
    const N = 100_000;
    const edits = Array(N).fill((draft: Draft<State>) => {
      draft.foo.counter++;
    });
    store.edit(edits);
    expect(store.state.foo.counter).toEqual(N);
  });

  it('notifies subscribers', () => {
    const store = createStore(initialState);
    const callback = jest.fn();

    store.subscribe(callback);

    store.edit((draft) => {
      draft.foo.counter += 1;
    });

    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(store, initialState);
  });

  it('does not notify unsubscribed subscribers', () => {
    const store = createStore(initialState);
    const callback = jest.fn();

    // Subscribe then immediately unsubscribe
    store.subscribe(callback)[Symbol.dispose]();

    // Make an arbitrary edit
    store.edit((draft) => {
      draft.foo.counter += 1;
    });

    expect(callback).not.toHaveBeenCalled();
  });
});

describe('sub-store', () => {
  test('edit', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);

    subStore.edit((draft) => {
      draft.counter += 1;
    });

    expect(subStore.state).toEqual({
      counter: 1,
      nested: {
        value: 42,
      },
    });

    expect(store.state).toEqual({
      foo: {
        counter: 1,
        nested: {
          value: 42,
        },
      },
    });
  });

  test('edit from root store', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);

    store.edit((draft) => {
      draft.foo.counter += 1;
    });

    expect(subStore.state).toEqual({
      counter: 1,
      nested: {
        value: 42,
      },
    });
  });

  it('can create more substores and edit', () => {
    const store = createStore(initialState);
    const fooState = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
    const nestedStore = fooState.createSubStore<Bar>(
      ['nested'],
      (x) => x as Bar,
    );

    nestedStore.edit((draft) => {
      draft.value += 1;
    });

    expect(nestedStore.state).toEqual({
      value: 43,
    });
  });

  it('notifies subscribers', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
    const callback = jest.fn();

    subStore.subscribe(callback);

    subStore.edit((draft) => {
      draft.counter += 1;
    });

    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(subStore, initialState.foo);
  });

  it('does not notify unsubscribed subscribers', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
    const callback = jest.fn();

    // Subscribe then immediately unsubscribe
    subStore.subscribe(callback)[Symbol.dispose]();

    // Make an arbitrary edit
    subStore.edit((draft) => {
      draft.counter += 1;
    });

    expect(callback).not.toHaveBeenCalled();
  });

  it('handles reading when path doesn\t exist in root store', () => {
    const store = createStore(initialState);

    // This target node is missing - baz doesn't exist in State
    const subStore = store.createSubStore<Foo>(['baz'], (x) => x as Foo);
    expect(subStore.state).toBe(undefined);
  });

  it("handles edit when path doesn't exist in root store", () => {
    const store = createStore(initialState);
    const value: Foo = {
      counter: 123,
      nested: {
        value: 456,
      },
    };

    // This target node is missing - baz doesn't exist in State
    const subStore = store.createSubStore<Foo>(['baz', 'quux'], () => value);

    // Edits should work just fine, but the root store will not be modified.
    subStore.edit((draft) => {
      draft.counter += 1;
    });
  });

  it('check subscriber only called once when edits made to undefined root path', () => {
    const store = createStore(initialState);
    const value: Foo = {
      counter: 123,
      nested: {
        value: 456,
      },
    };

    const callback = jest.fn();

    // This target node is missing - baz doesn't exist in State
    const subStore = store.createSubStore<Foo>(['baz', 'quux'], () => value);
    subStore.subscribe(callback);

    // Edits should work just fine, but the root store will not be modified.
    subStore.edit((draft) => {
      draft.counter += 1;
    });

    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(subStore, value);
  });

  it("notifies subscribers even when path doesn't exist in root store", () => {
    const store = createStore(initialState);
    const value: Foo = {
      counter: 123,
      nested: {
        value: 456,
      },
    };
    const subStore = store.createSubStore<Foo>(['baz', 'quux'], () => value);

    const callback = jest.fn();
    subStore.subscribe(callback);

    subStore.edit((draft) => {
      draft.counter += 1;
    });

    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(subStore, value);
  });

  it('notifies when relevant edits are made from root store', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
    const callback = jest.fn();

    // Subscribe on the proxy store
    subStore.subscribe(callback);

    // Edit the subtree from the root store
    store.edit((draft) => {
      draft.foo.counter++;
    });

    // Expect proxy callback called with correct subtree
    expect(callback).toHaveBeenCalledTimes(1);
    expect(callback).toHaveBeenCalledWith(subStore, initialState.foo);
  });

  it('ignores irrelevant edits from the root store', () => {
    const store = createStore(initialState);
    const nestedStore = store.createSubStore<Bar>(
      ['foo', 'nested'],
      (x) => x as Bar,
    );
    const callback = jest.fn();

    // Subscribe on the proxy store
    nestedStore.subscribe(callback);

    // Edit an irrelevant subtree on the root store
    store.edit((draft) => {
      draft.foo.counter++;
    });

    // Ensure proxy callback hasn't been called
    expect(callback).not.toHaveBeenCalled();
  });

  it('immutable [in]equality works', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], migrateFoo);
    const before = subStore.state;

    subStore.edit((draft) => {
      draft.counter += 1;
    });

    const after = subStore.state;

    // something has changed so root should not equal
    expect(before).not.toBe(after);

    // nested has not changed and so should be the before version.
    expect(before.nested).toBe(after.nested);
  });

  // This test depends on the migrate function - if it attempts to preserve
  // equality then we might have a chance, but our migrate function here does
  // not, and I'm not sure we can expect people do provide one that does.
  // TODO(stevegolton): See if we can get this working, regardless of migrate
  // function implementation.
  it.skip('unrelated state refs are still equal when modified from root store', () => {
    const store = createStore(initialState);
    const subStore = store.createSubStore<Foo>(['foo'], migrateFoo);
    const before = subStore.state;

    // Check that unrelated state is still the same even though subtree is
    // modified from the root store
    store.edit((draft) => {
      draft.foo.counter = 1234;
    });

    expect(before.nested).toBe(subStore.state.nested);
    expect(subStore.state.counter).toBe(1234);
  });

  it('works when underlying state is undefined', () => {
    interface RootState {
      dict: {[key: string]: unknown};
    }
    interface ProxyState {
      bar: string;
    }

    const store = createStore<RootState>({dict: {}});
    const migrate = (init: unknown) => (init ?? {bar: 'bar'}) as ProxyState;
    const subStore = store.createSubStore(['dict', 'foo'], migrate);

    // Check initial migration works, yet underlying store is untouched
    expect(subStore.state.bar).toBe('bar');
    expect(store.state.dict['foo']).toBe(undefined);

    // Check updates work
    subStore.edit((draft) => {
      draft.bar = 'baz';
    });
    expect(subStore.state.bar).toBe('baz');
    expect((store.state.dict['foo'] as ProxyState).bar).toBe('baz');
  });

  test('chained substores', () => {
    interface State {
      dict: {[key: string]: unknown};
    }

    interface FooState {
      bar: {
        baz: string;
      };
    }

    const store = createStore<State>({dict: {}});

    const DEFAULT_FOO_STATE: FooState = {bar: {baz: 'abc'}};
    const fooStore = store.createSubStore(
      ['dict', 'foo'],
      (init) => init ?? DEFAULT_FOO_STATE,
    );

    const subFooStore = fooStore.createSubStore(
      ['bar'],
      (x) => x as FooState['bar'],
    );

    // Since the entry for 'foo' will be undefined in the dict, we expect the
    // migrate function on fooStore to return DEFAULT_FOO_STATE, and thus the
    // state of the subFooStore will be DEFAULT_FOO_STATE.bar.
    expect(subFooStore.state).toEqual({baz: 'abc'});
  });
});
