// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library tests.dart2js.lookup_map_test;

import 'package:test/test.dart';
import 'compiler_helper.dart';

main() {
  Map<String, String> testDeclarations = {
    'types': r'''
      import 'package:lookup_map/lookup_map.dart';
      class A {}
      class B {}
      class C {}
      class D {}
      class E {}''',
    'const keys': r'''
      import 'package:lookup_map/lookup_map.dart';
      class Key { final name; const Key(this.name); }
      const A = const Key("A");
      const B = const Key("B");
      const C = const Key("C");
      const D = const Key("D");
      const E = const Key("E");''',
    'mixed keys': r'''
      import 'package:lookup_map/lookup_map.dart';
      class Key { final name; const Key(this.name); }
      const A = const Key("A");
      class B {}
      const C = const Key("C");
      class D {}
      const E = const Key("E");''',
  };

  testDeclarations.forEach((name, declarations) {
    group(name, () => _commonTests(declarations));
  });
  group('generic', _genericTests);
  group('metadata', _metadataTests);
  group('unsupported', _unsupportedKeysTests);
  group('mirrors', _mirrorsTests);
}

/// Common tests for both declarations that use Types or other const expressions
/// as keys. The argument [declaration] should contain a declaration for
/// constant keys named `A`, `B`, `C`, `D`, and `E`.
_commonTests(String declarations) {
  test('live entries are kept', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap(const [
            A, "the-text-for-A",
        ]);
        main() => print(map[A]);
    """);
    expect(generated, contains("the-text-for-A"));
  });

  test('live entries are kept - single-pair', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap.pair(A, "the-text-for-A");
        main() => print(map[A]);
    """);
    expect(generated, contains("the-text-for-A"));
  });

  test('unused entries are removed', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap(const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ]);
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('unused entries are removed - nested maps', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap(const [], const [
          const LookupMap(const [
              A, "the-text-for-A",
              B, "the-text-for-B",
          ]),
        ]);
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('unused entries are removed - single-pair', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap.pair(A, "the-text-for-A");
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('unused entries are removed - nested single-pair', () async {
    String generated = await compileAll("""
        import 'package:lookup_map/lookup_map.dart';
        $declarations
        const map = const LookupMap(const [], const [
          const LookupMap.pair(A, "the-text-for-A"),
          const LookupMap.pair(B, "the-text-for-B"),
        ]);
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('works if entries are declared separate from map', () async {
    String generated = await compileAll("""
        $declarations
        const entries = const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ];
        const map = const LookupMap(entries);
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('escaping entries disable tree-shaking', () async {
    String generated = await compileAll("""
        $declarations
        const entries = const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ];
        const map = const LookupMap(entries);
        main() {
          entries.forEach(print);
          print(map[A]);
        }
    """);
    expect(generated, contains("the-text-for-B"));
  });

  test('uses include recursively reachable data', () async {
    String generated = await compileAll("""
        $declarations
        const map = const LookupMap(const [
            A, const ["the-text-for-A", B],
            B, const ["the-text-for-B", C],
            C, const ["the-text-for-C"],
            D, const ["the-text-for-D", E],
            E, const ["the-text-for-E"],
        ]);
        main() => print(map[map[A][1]]);
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, contains("the-text-for-B"));
    expect(generated, contains("the-text-for-C"));
    expect(generated, isNot(contains("the-text-for-D")));
    expect(generated, isNot(contains("the-text-for-E")));
  });

  test('uses are found through newly discovered code', () async {
    String generated = await compileAll("""
        $declarations
        f1() => map[B][1]();
        f2() => E;
        const map = const LookupMap(const [
            A, const ["the-text-for-A", f1],
            B, const ["the-text-for-B", f2],
            C, const ["the-text-for-C"],
            D, const ["the-text-for-D"],
            E, const ["the-text-for-E"],
        ]);
        main() => print(map[A][1]());
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, contains("the-text-for-B"));
    expect(generated, isNot(contains("the-text-for-C")));
    expect(generated, isNot(contains("the-text-for-C")));
    expect(generated, contains("the-text-for-E"));
  });

  test('support subclassing LookupMap', () async {
    String generated = await compileAll("""
        $declarations
        class S extends LookupMap {
          const S(list) : super(list);
        }
        const map = const S(const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ]);

        main() => print(map[A]);
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, isNot(contains("the-text-for-B")));
  });

  test('constants keys are processed recursively', () async {
    String generated = await compileAll("""
        $declarations

        const nested = const [ B ];
        const map = const LookupMap(const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ]);
        main() => print(map[nested]);
    """);
    expect(generated, isNot(contains("the-text-for-A")));
    expect(generated, contains("the-text-for-B"));
  });
}

/// Tests specific to type keys, we ensure that generic type arguments are
/// considered.
_genericTests() {
  test('generic type allocations are considered used', () async {
    String generated = await compileAll(r"""
        import 'package:lookup_map/lookup_map.dart';
        class A{}
        class M<T>{ get type => T; }
        const map = const LookupMap(const [
            A, "the-text-for-A",
        ]);
        main() => print(map[new M<A>().type]);
    """);
    expect(generated, contains("the-text-for-A"));
  });

  test('generics in type signatures are ignored', () async {
    String generated = await compileAll(r"""
        import 'package:lookup_map/lookup_map.dart';
        class A{}
        class B{}
        class M<T>{ get type => T; }
        _factory(M<B> t) => t;
        const map = const LookupMap(const [
            A, const ["the-text-for-A", _factory],
            B, "the-text-for-B",
        ]);
        main() => print(map[A]);
    """);
    expect(generated, isNot(contains("the-text-for-B")));
  });

  // regression test for a failure when looking up `dynamic` in a generic.
  test('do not choke with dynamic type arguments', () async {
    await compileAll(r"""
        import 'package:lookup_map/lookup_map.dart';
        class A{}
        class M<T>{ get type => T; }
        const map = const LookupMap(const [
            A, "the-text-for-A",
        ]);
        main() => print(map[new M<dynamic>().type]);
    """);
  });
}

/// Sanity checks about metadata: it is ignored for codegen even though it is
/// visited during resolution.
_metadataTests() {
  test('metadata is ignored', () async {
    String generated = await compileAll(r"""
        import 'package:lookup_map/lookup_map.dart';
        class A{ const A(); }

        @A()
        class M {}
        const map = const LookupMap(const [
            A, "the-text-for-A",
        ]);
        main() => print(map[M]);
    """);
    expect(generated, isNot(contains("the-text-for-A")));
  });

  test('shared constants used in metadata are ignored', () async {
    String generated = await compileAll(r"""
        import 'package:lookup_map/lookup_map.dart';
        const annot = const B(foo: A);

        @B(foo: annot)
        class A{ const A(); }
        class B{ final Type foo; const B({this.foo}); }

        class M {}
        const map = const LookupMap(const [
            A, const ["the-text-for-A", annot]
        ]);
        main() => print(map[M]);
    """);
    expect(generated, isNot(contains("the-text-for-A")));
  });
}

_unsupportedKeysTests() {
  test('primitive and string keys are always kept', () async {
    String generated = await compileAll("""
        import 'package:lookup_map/lookup_map.dart';
        const A = "A";
        const B = "B";
        const map = const LookupMap(const [
            A, "the-text-for-A",
            B, "the-text-for-B",
            3, "the-text-for-3",
            1.1, "the-text-for-1.1",
            false, "the-text-for-false",
        ]);
        main() => print(map[A]);
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, contains("the-text-for-B"));
    expect(generated, contains("the-text-for-3"));
    expect(generated, contains("the-text-for-1.1"));
    expect(generated, contains("the-text-for-false"));
  });

  test('non-type const keys implementing equals are not removed', () async {
    String generated = await compileAll("""
        import 'package:lookup_map/lookup_map.dart';
        class Key {
          final name;
          const Key(this.name);
          int get hashCode => name.hashCode * 13;
          operator ==(other) => other is Key && name == other.name;
        }
        const A = const Key("A");
        const B = const Key("B");
        const map = const LookupMap(const [
            A, "the-text-for-A",
            B, "the-text-for-B",
        ]);
        main() => print(map[A]);
    """);
    expect(generated, contains("the-text-for-B"));
  });
}

_mirrorsTests() {
  test('retain entries if mirrors keep the type', () async {
    String generated = await compileAll("""
        import 'dart:mirrors';
        import 'package:lookup_map/lookup_map.dart';
        class A {}
        class B {}
        class C {}
        const map = const LookupMap(const [
          A, "the-text-for-A",
          B, "the-text-for-B",
          C, "the-text-for-C",
        ]);
        main() {
          reflectType(A);
          print(map[A]);
        }
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, contains("the-text-for-B"));
    expect(generated, contains("the-text-for-C"));
  });

  test('exclude entries if MirrorsUsed also exclude the type', () async {
    String generated = await compileAll("""
        library foo;
        @MirrorsUsed(targets: const [B])
        import 'dart:mirrors';
        import 'package:lookup_map/lookup_map.dart';
        class A {}
        class B {}
        class C {}
        const map = const LookupMap(const [
          A, "the-text-for-A",
          B, "the-text-for-B",
          C, "the-text-for-C",
        ]);
        main() {
          reflectType(A);
          print(map[A]);
        }
    """);
    expect(generated, contains("the-text-for-A"));
    expect(generated, contains("the-text-for-B"));
    expect(generated, isNot(contains("the-text-for-C")));
  });
}
