// 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.fileName, this.tokens, {
    this.colorSchemePrefix = 'Theme.of(context).colorScheme.',
    this.textThemePrefix = 'Theme.of(context).textTheme.'
  });

  static const String beginGeneratedComment = '''

// BEGIN GENERATED TOKEN PROPERTIES
''';

  static const String headerComment = '''

// Generated code to the end of this file. Do not edit by hand.
// These defaults are generated from the Material Design Token
// database by the script dev/tools/gen_defaults/bin/gen_defaults.dart.

''';

  static const String endGeneratedComment = '''

// END GENERATED TOKEN PROPERTIES
''';

  final String fileName;
  final Map<String, dynamic> tokens;
  final String colorSchemePrefix;
  final String textThemePrefix;

  /// Replace or append the contents of the file with the text from [generate].
  ///
  /// If the file already contains generated block at the end, 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 {
    String contents = File(fileName).readAsStringSync();
    final int previousGeneratedIndex = contents.indexOf(beginGeneratedComment);
    if (previousGeneratedIndex != -1) {
      contents = contents.substring(0, previousGeneratedIndex);
    }
    final StringBuffer buffer = StringBuffer(contents);
    buffer.write(beginGeneratedComment);
    buffer.write(headerComment);
    buffer.write(generate());
    buffer.write(endGeneratedComment);
    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"]}';
  }
}
