// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(davidmartos96): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/142716
// Fails with "flutter test --test-randomize-ordering-seed=20240201"
@Tags(<String>['no-shuffle'])
library;

import 'dart:async';
import 'dart:io';

import 'package:gen_defaults/template.dart';
import 'package:gen_defaults/token_logger.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

void main() {
  final TokenLogger logger = tokenLogger;
  // Required init with empty at least once to init late fields.
  // Then we can use the `clear` method.
  logger.init(allTokens: <String, dynamic>{}, versionMap: <String, List<String>>{});

  setUp(() {
    // Cleanup the global token logger before each test, to not be tied to a particular
    // test order.
    logger.clear();
  });

  test('Templates will append to the end of a file', () {
    final Directory tempDir = Directory.systemTemp.createTempSync('gen_defaults');
    try {
      // Create a temporary file with some content.
      final File tempFile = File(path.join(tempDir.path, 'test_template.txt'));
      tempFile.createSync();
      tempFile.writeAsStringSync('''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.
''');

      // Have a test template append new parameterized content to the end of
      // the file.
      final Map<String, dynamic> tokens = <String, dynamic>{'version': '0.0', 'foo': 'Foobar', 'bar': 'Barfoo'};
      TestTemplate('Test', tempFile.path, tokens).updateFile();

      expect(tempFile.readAsStringSync(), '''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Test

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'Foobar';
static final String tokenBar = 'Barfoo';

// END GENERATED TOKEN PROPERTIES - Test
''');

    } finally {
      tempDir.deleteSync(recursive: true);
    }
  });

  test('Templates will update over previously generated code at the end of a file', () {
    final Directory tempDir = Directory.systemTemp.createTempSync('gen_defaults');
    try {
      // Create a temporary file with some content.
      final File tempFile = File(path.join(tempDir.path, 'test_template.txt'));
      tempFile.createSync();
      tempFile.writeAsStringSync('''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Test

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'Foobar';
static final String tokenBar = 'Barfoo';

// END GENERATED TOKEN PROPERTIES - Test
''');

      // Have a test template append new parameterized content to the end of
      // the file.
      final Map<String, dynamic> tokens = <String, dynamic>{'version': '0.0', 'foo': 'foo', 'bar': 'bar'};
      TestTemplate('Test', tempFile.path, tokens).updateFile();

      expect(tempFile.readAsStringSync(), '''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Test

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'foo';
static final String tokenBar = 'bar';

// END GENERATED TOKEN PROPERTIES - Test
''');

    } finally {
      tempDir.deleteSync(recursive: true);
    }
  });

  test('Multiple templates can modify different code blocks in the same file', () {
    final Directory tempDir = Directory.systemTemp.createTempSync('gen_defaults');
    try {
      // Create a temporary file with some content.
      final File tempFile = File(path.join(tempDir.path, 'test_template.txt'));
      tempFile.createSync();
      tempFile.writeAsStringSync('''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.
''');

      // Update file with a template for 'Block 1'
      {
        final Map<String, dynamic> tokens = <String, dynamic>{'version': '0.0', 'foo': 'foo', 'bar': 'bar'};
        TestTemplate('Block 1', tempFile.path, tokens).updateFile();
      }
      expect(tempFile.readAsStringSync(), '''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Block 1

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'foo';
static final String tokenBar = 'bar';

// END GENERATED TOKEN PROPERTIES - Block 1
''');

      // Update file with a template for 'Block 2', which should append but not
      // disturb the code in 'Block 1'.
      {
        final Map<String, dynamic> tokens = <String, dynamic>{'version': '0.0', 'foo': 'bar', 'bar': 'foo'};
        TestTemplate('Block 2', tempFile.path, tokens).updateFile();
      }
      expect(tempFile.readAsStringSync(), '''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Block 1

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'foo';
static final String tokenBar = 'bar';

// END GENERATED TOKEN PROPERTIES - Block 1

// BEGIN GENERATED TOKEN PROPERTIES - Block 2

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'bar';
static final String tokenBar = 'foo';

// END GENERATED TOKEN PROPERTIES - Block 2
''');

      // Update 'Block 1' again which should just update that block,
      // leaving 'Block 2' undisturbed.
      {
        final Map<String, dynamic> tokens = <String, dynamic>{'version': '0.0', 'foo': 'FOO', 'bar': 'BAR'};
        TestTemplate('Block 1', tempFile.path, tokens).updateFile();
      }
      expect(tempFile.readAsStringSync(), '''
// This is a file with stuff in it.
// This part shouldn't be changed by
// the template.

// BEGIN GENERATED TOKEN PROPERTIES - Block 1

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'FOO';
static final String tokenBar = 'BAR';

// END GENERATED TOKEN PROPERTIES - Block 1

// BEGIN GENERATED TOKEN PROPERTIES - Block 2

// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
//   dev/tools/gen_defaults/bin/gen_defaults.dart.

static final String tokenFoo = 'bar';
static final String tokenBar = 'foo';

// END GENERATED TOKEN PROPERTIES - Block 2
''');

    } finally {
      tempDir.deleteSync(recursive: true);
    }
  });

  test('Templates can get proper shapes from given data', () {
    const Map<String, dynamic> tokens = <String, dynamic>{
      'foo.shape': 'shape.large',
      'bar.shape': 'shape.full',
      'shape.large': <String, dynamic>{
        'family': 'SHAPE_FAMILY_ROUNDED_CORNERS',
        'topLeft': 1.0,
        'topRight': 2.0,
        'bottomLeft': 3.0,
        'bottomRight': 4.0,
      },
      'shape.full': <String, dynamic>{
        'family': 'SHAPE_FAMILY_CIRCULAR',
      },
    };
    final TestTemplate template = TestTemplate('Test', 'foobar.dart', tokens);
    expect(template.shape('foo'), 'const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(1.0), topRight: Radius.circular(2.0), bottomLeft: Radius.circular(3.0), bottomRight: Radius.circular(4.0)))');
    expect(template.shape('bar'), 'const StadiumBorder()');
  });

  group('Tokens logger', () {
    final List<String> printLog = List<String>.empty(growable: true);
    final Map<String, List<String>> versionMap = <String, List<String>>{};
    final Map<String, dynamic> allTokens = <String, dynamic>{};

    // Add to printLog instead of printing to stdout
    void Function() overridePrint(void Function() testFn) => () {
      final ZoneSpecification spec = ZoneSpecification(
        print: (_, __, ___, String msg) {
          printLog.add(msg);
        }
      );
      return Zone.current.fork(specification: spec).run<void>(testFn);
    };

    setUp(() {
      logger.init(allTokens: allTokens, versionMap: versionMap);
    });

    tearDown(() {
      logger.clear();
      printLog.clear();
      versionMap.clear();
      allTokens.clear();
    });

    String errorColoredString(String str) => '\x1B[31m$str\x1B[0m';

    const Map<String, List<String>> testVersions = <String, List<String>>{
      'v1.0.0': <String>['file_1.json'],
      'v2.0.0': <String>['file_2.json, file_3.json'],
    };

    test('can print empty usage', overridePrint(() {
      logger.printVersionUsage(verbose: true);
      expect(printLog, contains('Versions used: '));

      logger.printTokensUsage(verbose: true);
      expect(printLog, contains('Tokens used: 0/0'));
    }));

    test('can print version usage', overridePrint(() {
      versionMap.addAll(testVersions);

      logger.printVersionUsage(verbose: false);

      expect(printLog, contains('Versions used: v1.0.0, v2.0.0'));
    }));

    test('can print version usage (verbose)', overridePrint(() {
      versionMap.addAll(testVersions);

      logger.printVersionUsage(verbose: true);

      expect(printLog, contains('Versions used: v1.0.0, v2.0.0'));
      expect(printLog, contains('  v1.0.0:'));
      expect(printLog, contains('    file_1.json'));
      expect(printLog, contains('  v2.0.0:'));
      expect(printLog, contains('    file_2.json, file_3.json'));
    }));

    test('can log and print tokens usage', overridePrint(() {
      allTokens['foo'] = 'value';

      logger.log('foo');
      logger.printTokensUsage(verbose: false);

      expect(printLog, contains('Tokens used: 1/1'));
    }));

    test('can log and print tokens usage (verbose)', overridePrint(() {
      allTokens['foo'] = 'value';

      logger.log('foo');
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ foo'));
      expect(printLog, contains('Tokens used: 1/1'));
    }));

    test('detects invalid logs', overridePrint(() {
      allTokens['foo'] = 'value';

      logger.log('baz');
      logger.log('foobar');
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('❌ foo'));
      expect(printLog, contains('Tokens used: 0/1'));
      expect(printLog, contains(errorColoredString('Some referenced tokens do not exist: 2')));
      expect(printLog, contains('  baz'));
      expect(printLog, contains('  foobar'));
    }));

    test("color function doesn't log when providing a default", overridePrint(() {
      allTokens['color_foo_req'] = 'value';

      // color_foo_opt is not available, but because it has a default value, it won't warn about it

      TestColorTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ color_foo_req'));
      expect(printLog, contains('Tokens used: 1/1'));
    }));

    test('color function logs when not providing a default', overridePrint(() {
      // Nor color_foo_req or color_foo_opt are available, but only color_foo_req will be logged.
      // This mimics a token being removed, but expected to exist.

      TestColorTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('Tokens used: 0/0'));
      expect(printLog, contains(errorColoredString('Some referenced tokens do not exist: 1')));
      expect(printLog, contains('  color_foo_req'));
    }));

    test('border function logs width token when available', overridePrint(() {
      allTokens['border_foo.color'] = 'red';
      allTokens['border_foo.width'] = 3.0;

      TestBorderTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ border_foo.color'));
      expect(printLog, contains('✅ border_foo.width'));
      expect(printLog, contains('Tokens used: 2/2'));
    }));

    test('border function logs height token when width token not available', overridePrint(() {
      allTokens['border_foo.color'] = 'red';
      allTokens['border_foo.height'] = 3.0;

      TestBorderTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ border_foo.color'));
      expect(printLog, contains('✅ border_foo.height'));
      expect(printLog, contains('Tokens used: 2/2'));
    }));

    test("border function doesn't log when width or height tokens not available", overridePrint(() {
      allTokens['border_foo.color'] = 'red';

      TestBorderTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ border_foo.color'));
      expect(printLog, contains('Tokens used: 1/1'));
    }));

    test('can log and dump versions & tokens to a file', overridePrint(() {
      versionMap.addAll(testVersions);
      allTokens['foo'] = 'value';
      allTokens['bar'] = 'value';

      logger.log('foo');
      logger.log('bar');
      logger.dumpToFile('test.json');

      final String fileContent = File('test.json').readAsStringSync();
      expect(fileContent, contains('Versions used, v1.0.0, v2.0.0'));
      expect(fileContent, contains('bar,'));
      expect(fileContent, contains('foo'));
    }));

    test('integration test', overridePrint(() {
      allTokens['foo'] = 'value';
      allTokens['bar'] = 'value';

      TestTemplate('block', 'filename', allTokens).generate();
      logger.printTokensUsage(verbose: true);

      expect(printLog, contains('✅ foo'));
      expect(printLog, contains('✅ bar'));
      expect(printLog, contains('Tokens used: 2/2'));
    }));
  });
}

class TestTemplate extends TokenTemplate {
  TestTemplate(super.blockName, super.fileName, super.tokens);

  @override
  String generate() => '''
static final String tokenFoo = '${getToken('foo')}';
static final String tokenBar = '${getToken('bar')}';
''';
}

class TestColorTemplate extends TokenTemplate {
  TestColorTemplate(super.blockName, super.fileName, super.tokens);

  @override
  String generate() => '''
static final Color color_1 = '${color('color_foo_req')}';
static final Color color_2 = '${color('color_foo_opt', 'Colors.red')}';
''';
}

class TestBorderTemplate extends TokenTemplate {
  TestBorderTemplate(super.blockName, super.fileName, super.tokens);

  @override
  String generate() => '''
static final BorderSide border = '${border('border_foo')}';
''';
}
