// 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.

import 'dart:io';

abstract class TokenTemplate {
  const TokenTemplate(this.blockName, this.fileName, this.tokens, {
    this.colorSchemePrefix = 'Theme.of(context).colorScheme.',
    this.textThemePrefix = 'Theme.of(context).textTheme.'
  });

  /// Name of the code block that this template will generate.
  ///
  /// Used to identify an existing block when updating it.
  final String blockName;

  /// Name of the file that will be updated with the generated code.
  final String fileName;

  /// Map of token data extracted from the Material Design token database.
  final Map<String, dynamic> tokens;

  /// Optional prefix prepended to color definitions.
  ///
  /// Defaults to 'Theme.of(context).colorScheme.'
  final String colorSchemePrefix;

  /// Optional prefix prepended to text style definitians.
  ///
  /// Defaults to 'Theme.of(context).textTheme.'
  final String textThemePrefix;

  static const String beginGeneratedComment = '''

// BEGIN GENERATED TOKEN PROPERTIES''';

  static const String headerComment = '''

// 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 const String endGeneratedComment = '''

// END GENERATED TOKEN PROPERTIES''';

  /// Replace or append the contents of the file with the text from [generate].
  ///
  /// If the file already contains a generated text block matching the
  /// [blockName], it will be replaced by the [generate] output. Otherwise
  /// the content will just be appended to the end of the file.
  Future<void> updateFile() async {
    final String contents = File(fileName).readAsStringSync();
    final String beginComment = '$beginGeneratedComment - $blockName\n';
    final String endComment = '$endGeneratedComment - $blockName\n';
    final int beginPreviousBlock = contents.indexOf(beginComment);
    final int endPreviousBlock = contents.indexOf(endComment);
    late String contentBeforeBlock;
    late String contentAfterBlock;
    if (beginPreviousBlock != -1) {
      if (endPreviousBlock < beginPreviousBlock) {
        print('Unable to find block named $blockName in $fileName, skipping code generation.');
        return;
      }
      // Found a valid block matching the name, so record the content before and after.
      contentBeforeBlock = contents.substring(0, beginPreviousBlock);
      contentAfterBlock = contents.substring(endPreviousBlock + endComment.length);
    } else {
      // Just append to the bottom.
      contentBeforeBlock = contents;
      contentAfterBlock = '';
    }

    final StringBuffer buffer = StringBuffer(contentBeforeBlock);
    buffer.write(beginComment);
    buffer.write(headerComment);
    buffer.write('// Token database version: ${tokens['version']}\n\n');
    buffer.write(generate());
    buffer.write(endComment);
    buffer.write(contentAfterBlock);
    File(fileName).writeAsStringSync(buffer.toString());
  }

  /// Provide the generated content for the template.
  ///
  /// This abstract method needs to be implemented by subclasses
  /// to provide the content that [updateFile] will append to the
  /// bottom of the file.
  String generate();

  /// Generate a [ColorScheme] color name for the given token.
  ///
  /// If there is a value for the given token, this will return
  /// the value prepended with [colorSchemePrefix].
  ///
  /// Otherwise it will return 'null'.
  ///
  /// See also:
  ///   * [componentColor], that provides support for an optional opacity.
  String color(String colorToken) {
    return tokens.containsKey(colorToken)
      ? '$colorSchemePrefix${tokens[colorToken]}'
      : 'null';
  }

  /// Generate a [ColorScheme] color name for the given component's color
  /// with opacity if available.
  ///
  /// If there is a value for the given component's color, this will return
  /// the value prepended with [colorSchemePrefix]. If there is also
  /// an opacity specified for the component, then the returned value
  /// will include this opacity calculation.
  ///
  /// If there is no value for the component's color, 'null' will be returned.
  ///
  /// See also:
  ///   * [color], that provides support for looking up a raw color token.
  String componentColor(String componentToken) {
    final String colorToken = '$componentToken.color';
    if (!tokens.containsKey(colorToken)) {
      return 'null';
    }
    String value = color(colorToken);
    final String opacityToken = '$componentToken.opacity';
    if (tokens.containsKey(opacityToken)) {
      value += '.withOpacity(${opacity(opacityToken)})';
    }
    return value;
  }

  /// Generate the opacity value for the given token.
  String? opacity(String token) {
    final dynamic value = tokens[token];
    if (value == null) {
      return null;
    }
    if (value is double) {
      return value.toString();
    }
    return tokens[value].toString();
  }

  /// Generate an elevation value for the given component token.
  String elevation(String componentToken) {
    return tokens[tokens['$componentToken.elevation']!]!.toString();
  }

  /// Generate a shape constant for the given component token.
  ///
  /// Currently supports family:
  ///   - "SHAPE_FAMILY_ROUNDED_CORNERS" which maps to [RoundedRectangleBorder].
  ///   - "SHAPE_FAMILY_CIRCULAR" which maps to a [StadiumBorder].
  String shape(String componentToken) {
    final Map<String, dynamic> shape = tokens[tokens['$componentToken.shape']!]! as Map<String, dynamic>;
    switch (shape['family']) {
      case 'SHAPE_FAMILY_ROUNDED_CORNERS':
        return 'const RoundedRectangleBorder(borderRadius: '
            'BorderRadius.only('
            'topLeft: Radius.circular(${shape['topLeft']}), '
            'topRight: Radius.circular(${shape['topRight']}), '
            'bottomLeft: Radius.circular(${shape['bottomLeft']}), '
            'bottomRight: Radius.circular(${shape['bottomRight']})))';
      case 'SHAPE_FAMILY_CIRCULAR':
        return 'const StadiumBorder()';
    }
    print('Unsupported shape family type: ${shape['family']} for $componentToken');
    return '';
  }

  /// Generate a [BorderSide] for the given component.
  String border(String componentToken) {
    if (!tokens.containsKey('$componentToken.color')) {
      return 'null';
    }
    final String borderColor = componentColor(componentToken);
    final double width = (tokens['$componentToken.width'] ?? 1.0) as double;
    return 'BorderSide(color: $borderColor${width != 1.0 ? ", width: $width" : ""})';
  }

  /// Generate a [TextTheme] text style name for the given component token.
  String textStyle(String componentToken) {
    return '$textThemePrefix${tokens["$componentToken.text-style"]}';
  }
}
