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

// Regenerates a Dart file with a class containing IconData constants.
// See https://github.com/flutter/flutter/blob/main/docs/libraries/material/Updating-Material-Design-Fonts-%26-Icons.md
// Should be idempotent with:
// dart dev/tools/update_icons.dart --new-codepoints bin/cache/artifacts/material_fonts/codepoints

import 'dart:collection';
import 'dart:convert' show LineSplitter;
import 'dart:io';

import 'package:args/args.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

const String _iconsPathOption = 'icons';
const String _iconsTemplatePathOption = 'icons-template';
const String _newCodepointsPathOption = 'new-codepoints';
const String _oldCodepointsPathOption = 'old-codepoints';
const String _fontFamilyOption = 'font-family';
const String _possibleStyleSuffixesOption = 'style-suffixes';
const String _classNameOption = 'class-name';
const String _enforceSafetyChecks = 'enforce-safety-checks';
const String _dryRunOption = 'dry-run';

const String _defaultIconsPath = 'packages/flutter/lib/src/material/icons.dart';
const String _defaultNewCodepointsPath = 'codepoints';
const String _defaultOldCodepointsPath = 'bin/cache/artifacts/material_fonts/codepoints';
const String _defaultFontFamily = 'MaterialIcons';
const List<String> _defaultPossibleStyleSuffixes = <String>['_outlined', '_rounded', '_sharp'];
const String _defaultClassName = 'Icons';
const String _defaultDemoFilePath = '/tmp/new_icons_demo.dart';

const String _beginGeneratedMark = '// BEGIN GENERATED ICONS';
const String _endGeneratedMark = '// END GENERATED ICONS';
const String _beginPlatformAdaptiveGeneratedMark = '// BEGIN GENERATED PLATFORM ADAPTIVE ICONS';
const String _endPlatformAdaptiveGeneratedMark = '// END GENERATED PLATFORM ADAPTIVE ICONS';

const Map<String, List<String>> _platformAdaptiveIdentifiers = <String, List<String>>{
  // Mapping of Flutter IDs to an Android/agnostic ID and an iOS ID.
  // Flutter IDs can be anything, but should be chosen to be agnostic.
  'arrow_back': <String>['arrow_back', 'arrow_back_ios'],
  'arrow_forward': <String>['arrow_forward', 'arrow_forward_ios'],
  'flip_camera': <String>['flip_camera_android', 'flip_camera_ios'],
  'more': <String>['more_vert', 'more_horiz'],
  'share': <String>['share', 'ios_share'],
};

// Rewrite certain Flutter IDs (numbers) using prefix matching.
const Map<String, String> _identifierPrefixRewrites = <String, String>{
  '1': 'one_',
  '2': 'two_',
  '3': 'three_',
  '4': 'four_',
  '5': 'five_',
  '6': 'six_',
  '7': 'seven_',
  '8': 'eight_',
  '9': 'nine_',
  '10': 'ten_',
  '11': 'eleven_',
  '12': 'twelve_',
  '13': 'thirteen_',
  '14': 'fourteen_',
  '15': 'fifteen_',
  '16': 'sixteen_',
  '17': 'seventeen_',
  '18': 'eighteen_',
  '19': 'nineteen_',
  '20': 'twenty_',
  '21': 'twenty_one_',
  '22': 'twenty_two_',
  '23': 'twenty_three_',
  '24': 'twenty_four_',
  '30': 'thirty_',
  '60': 'sixty_',
  '123': 'onetwothree',
  '360': 'threesixty',
  '2d': 'twod',
  '3d': 'threed',
  '3d_rotation': 'threed_rotation',
};

// Rewrite certain Flutter IDs (reserved keywords) using exact matching.
const Map<String, String> _identifierExactRewrites = <String, String>{
  'class': 'class_',
  'new': 'new_',
  'switch': 'switch_',
  'try': 'try_sms_star',
  'door_back': 'door_back_door',
  'door_front': 'door_front_door',
};

const Set<String> _iconsMirroredWhenRTL = <String>{
  // This list is obtained from:
  // https://developers.google.com/fonts/docs/material_icons#which_icons_should_be_mirrored_for_rtl
  'arrow_back',
  'arrow_back_ios',
  'arrow_forward',
  'arrow_forward_ios',
  'arrow_left',
  'arrow_right',
  'assignment',
  'assignment_return',
  'backspace',
  'battery_unknown',
  'call_made',
  'call_merge',
  'call_missed',
  'call_missed_outgoing',
  'call_received',
  'call_split',
  'chevron_left',
  'chevron_right',
  'chrome_reader_mode',
  'device_unknown',
  'dvr',
  'event_note',
  'featured_play_list',
  'featured_video',
  'first_page',
  'flight_land',
  'flight_takeoff',
  'format_indent_decrease',
  'format_indent_increase',
  'format_list_bulleted',
  'forward',
  'functions',
  'help',
  'help_outline',
  'input',
  'keyboard_backspace',
  'keyboard_tab',
  'label',
  'label_important',
  'label_outline',
  'last_page',
  'launch',
  'list',
  'live_help',
  'mobile_screen_share',
  'multiline_chart',
  'navigate_before',
  'navigate_next',
  'next_week',
  'note',
  'open_in',
  'playlist_add',
  'queue_music',
  'redo',
  'reply',
  'reply_all',
  'screen_share',
  'send',
  'short_text',
  'show_chart',
  'sort',
  'star_half',
  'subject',
  'trending_flat',
  'toc',
  'trending_down',
  'trending_up',
  'undo',
  'view_list',
  'view_quilt',
  'wrap_text',
};

void main(List<String> args) {
  // If we're run from the `tools` dir, set the cwd to the repo root.
  if (path.basename(Directory.current.path) == 'tools') {
    Directory.current = Directory.current.parent.parent;
  }

  final ArgResults argResults = _handleArguments(args);

  final iconsFile = File(path.normalize(path.absolute(argResults[_iconsPathOption] as String)));
  if (!iconsFile.existsSync()) {
    stderr.writeln('Error: Icons file not found: ${iconsFile.path}');
    exit(1);
  }
  final iconsTemplateFile = File(
    path.normalize(path.absolute(argResults[_iconsTemplatePathOption] as String)),
  );
  if (!iconsTemplateFile.existsSync()) {
    stderr.writeln('Error: Icons template file not found: ${iconsTemplateFile.path}');
    exit(1);
  }
  final newCodepointsFile = File(argResults[_newCodepointsPathOption] as String);
  if (!newCodepointsFile.existsSync()) {
    stderr.writeln('Error: New codepoints file not found: ${newCodepointsFile.path}');
    exit(1);
  }
  final oldCodepointsFile = File(argResults[_oldCodepointsPathOption] as String);
  if (!oldCodepointsFile.existsSync()) {
    stderr.writeln('Error: Old codepoints file not found: ${oldCodepointsFile.path}');
    exit(1);
  }

  final String newCodepointsString = newCodepointsFile.readAsStringSync();
  final Map<String, String> newTokenPairMap = stringToTokenPairMap(newCodepointsString);

  final String oldCodepointsString = oldCodepointsFile.readAsStringSync();
  final Map<String, String> oldTokenPairMap = stringToTokenPairMap(oldCodepointsString);

  stderr.writeln('Performing safety checks');
  final bool isSuperset = testIsSuperset(newTokenPairMap, oldTokenPairMap);
  final bool isStable = testIsStable(newTokenPairMap, oldTokenPairMap);
  if ((!isSuperset || !isStable) && argResults[_enforceSafetyChecks] as bool) {
    exit(1);
  }
  final String iconsTemplateContents = iconsTemplateFile.readAsStringSync();

  stderr.writeln(
    "Generating icons ${argResults[_dryRunOption] as bool ? '' : 'to ${iconsFile.path}'}",
  );
  final String newIconsContents = _regenerateIconsFile(
    iconsTemplateContents,
    newTokenPairMap,
    argResults[_fontFamilyOption] as String,
    argResults[_classNameOption] as String,
    argResults[_enforceSafetyChecks] as bool,
  );

  if (argResults[_dryRunOption] as bool) {
    stdout.write(newIconsContents);
  } else {
    iconsFile.writeAsStringSync(newIconsContents);

    final sortedNewTokenPairMap = SplayTreeMap<String, String>.of(newTokenPairMap);
    _regenerateCodepointsFile(oldCodepointsFile, sortedNewTokenPairMap);

    sortedNewTokenPairMap.removeWhere(
      (String key, String value) => oldTokenPairMap.containsKey(key),
    );
    _generateIconDemo(File(_defaultDemoFilePath), sortedNewTokenPairMap);
  }
}

ArgResults _handleArguments(List<String> args) {
  final argParser = ArgParser()
    ..addOption(
      _iconsPathOption,
      defaultsTo: _defaultIconsPath,
      help: 'Location of the material icons file',
    )
    ..addOption(
      _iconsTemplatePathOption,
      defaultsTo: _defaultIconsPath,
      help: 'Location of the material icons file template. Usually the same as --$_iconsPathOption',
    )
    ..addOption(
      _newCodepointsPathOption,
      defaultsTo: _defaultNewCodepointsPath,
      help: 'Location of the new codepoints directory',
    )
    ..addOption(
      _oldCodepointsPathOption,
      defaultsTo: _defaultOldCodepointsPath,
      help: 'Location of the existing codepoints directory',
    )
    ..addOption(
      _fontFamilyOption,
      defaultsTo: _defaultFontFamily,
      help: 'The font family to use for the IconData constants',
    )
    ..addMultiOption(
      _possibleStyleSuffixesOption,
      defaultsTo: _defaultPossibleStyleSuffixes,
      help:
          'A comma-separated list of suffixes (typically an optional '
          'family + a style) e.g. _outlined, _monoline_filled',
    )
    ..addOption(
      _classNameOption,
      defaultsTo: _defaultClassName,
      help: 'The containing class for all icons',
    )
    ..addFlag(
      _enforceSafetyChecks,
      defaultsTo: true,
      help: 'Whether to exit if safety checks fail (e.g. codepoints are missing or unstable',
    )
    ..addFlag(_dryRunOption);
  argParser.addFlag(
    'help',
    abbr: 'h',
    negatable: false,
    callback: (bool help) {
      if (help) {
        print(argParser.usage);
        exit(1);
      }
    },
  );
  return argParser.parse(args);
}

Map<String, String> stringToTokenPairMap(String codepointData) {
  final Iterable<String> cleanData = LineSplitter.split(
    codepointData,
  ).map((String line) => line.trim()).where((String line) => line.isNotEmpty);

  final pairs = <String, String>{};

  for (final line in cleanData) {
    final List<String> tokens = line.split(' ');
    if (tokens.length != 2) {
      throw FormatException('Unexpected codepoint data: $line');
    }
    pairs.putIfAbsent(tokens[0], () => tokens[1]);
  }

  return pairs;
}

String _regenerateIconsFile(
  String templateFileContents,
  Map<String, String> tokenPairMap,
  String fontFamily,
  String className,
  bool enforceSafetyChecks,
) {
  final List<Icon> newIcons = tokenPairMap.entries
      .map(
        (MapEntry<String, String> entry) =>
            Icon(entry, fontFamily: fontFamily, className: className),
      )
      .toList();
  newIcons.sort((Icon a, Icon b) => a._compareTo(b));

  final buf = StringBuffer();
  var generating = false;

  for (final String line in LineSplitter.split(templateFileContents)) {
    if (!generating) {
      buf.writeln(line);
    }

    // Generate for PlatformAdaptiveIcons
    if (line.contains(_beginPlatformAdaptiveGeneratedMark)) {
      generating = true;
      final platformAdaptiveDeclarations = <String>[];
      _platformAdaptiveIdentifiers.forEach((String flutterId, List<String> ids) {
        // Automatically finds and generates all icon declarations.
        for (final style in <String>['', '_outlined', '_rounded', '_sharp']) {
          try {
            final Icon agnosticIcon = newIcons.firstWhere(
              (Icon icon) => icon.id == '${ids[0]}$style',
              orElse: () => throw ids[0],
            );
            final Icon iOSIcon = newIcons.firstWhere(
              (Icon icon) => icon.id == '${ids[1]}$style',
              orElse: () => throw ids[1],
            );
            platformAdaptiveDeclarations.add(
              agnosticIcon.platformAdaptiveDeclaration('$flutterId$style', iOSIcon),
            );
          } catch (e) {
            if (style == '') {
              // Throw an error for baseline icons.
              stderr.writeln("❌ Platform adaptive icon '$e' not found.");
              if (enforceSafetyChecks) {
                stderr.writeln('Safety checks failed');
                exit(1);
              }
            } else {
              // Ignore errors for styled icons since some don't exist.
            }
          }
        }
      });
      buf.write(platformAdaptiveDeclarations.join());
    } else if (line.contains(_endPlatformAdaptiveGeneratedMark)) {
      generating = false;
      buf.writeln(line);
    }

    // Generate for Icons
    if (line.contains(_beginGeneratedMark)) {
      generating = true;
      final String iconDeclarationsString = newIcons
          .map((Icon icon) => icon.fullDeclaration)
          .join();
      buf.write(iconDeclarationsString);
    } else if (line.contains(_endGeneratedMark)) {
      generating = false;
      buf.writeln(line);
    }
  }
  return buf.toString();
}

@visibleForTesting
bool testIsSuperset(Map<String, String> newCodepoints, Map<String, String> oldCodepoints) {
  final Set<String> newCodepointsSet = newCodepoints.keys.toSet();
  final Set<String> oldCodepointsSet = oldCodepoints.keys.toSet();

  final int diff = newCodepointsSet.length - oldCodepointsSet.length;
  if (diff > 0) {
    stderr.writeln('🆕 $diff new codepoints: ${newCodepointsSet.difference(oldCodepointsSet)}');
  }
  if (!newCodepointsSet.containsAll(oldCodepointsSet)) {
    stderr.writeln(
      '❌ new codepoints file does not contain all ${oldCodepointsSet.length} '
      'existing codepoints. Missing: ${oldCodepointsSet.difference(newCodepointsSet)}',
    );
    return false;
  } else {
    stderr.writeln(
      '✅ new codepoints file contains all ${oldCodepointsSet.length} existing codepoints',
    );
  }
  return true;
}

@visibleForTesting
bool testIsStable(Map<String, String> newCodepoints, Map<String, String> oldCodepoints) {
  final int oldCodepointsCount = oldCodepoints.length;
  final unstable = <String>[
    for (final MapEntry<String, String>(:String key, :String value) in oldCodepoints.entries)
      if (newCodepoints.containsKey(key) && value != newCodepoints[key]) key,
  ];

  if (unstable.isNotEmpty) {
    stderr.writeln(
      '❌ out of $oldCodepointsCount existing codepoints, ${unstable.length} were unstable: $unstable',
    );
    return false;
  } else {
    stderr.writeln('✅ all existing $oldCodepointsCount codepoints are stable');
    return true;
  }
}

void _regenerateCodepointsFile(File oldCodepointsFile, Map<String, String> tokenPairMap) {
  stderr.writeln('Regenerating old codepoints file ${oldCodepointsFile.path}');

  final buf = StringBuffer();
  tokenPairMap.forEach((String key, String value) => buf.writeln('$key $value'));
  oldCodepointsFile.writeAsStringSync(buf.toString());
}

void _generateIconDemo(File demoFilePath, Map<String, String> tokenPairMap) {
  if (tokenPairMap.isEmpty) {
    stderr.writeln('No new icons, skipping generating icon demo');
    return;
  }
  stderr.writeln('Generating icon demo at $_defaultDemoFilePath');

  final newIconUsages = StringBuffer();
  for (final MapEntry<String, String> entry in tokenPairMap.entries) {
    newIconUsages.writeln(Icon(entry).usage);
  }
  final demoFileContents =
      '''
    import 'package:flutter/material.dart';

    void main() => runApp(const IconDemo());

    class IconDemo extends StatelessWidget {
      const IconDemo({ Key? key }) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Wrap(
              children: const [
                $newIconUsages
              ],
            ),
          ),
        );
      }
    }
    ''';
  demoFilePath.writeAsStringSync(demoFileContents);
}

class Icon {
  // Parse tokenPair (e.g. {"6_ft_apart_outlined": "e004"}).
  Icon(
    MapEntry<String, String> tokenPair, {
    this.fontFamily = _defaultFontFamily,
    this.possibleStyleSuffixes = _defaultPossibleStyleSuffixes,
    this.className = _defaultClassName,
  }) {
    id = tokenPair.key;
    hexCodepoint = tokenPair.value;

    // Determine family and HTML class suffix for Dartdoc.
    if (id.endsWith('_gm_outlined')) {
      dartdocFamily = 'GM';
      dartdocHtmlSuffix = '-outlined';
    } else if (id.endsWith('_gm_filled')) {
      dartdocFamily = 'GM';
      dartdocHtmlSuffix = '-filled';
    } else if (id.endsWith('_monoline_outlined')) {
      dartdocFamily = 'Monoline';
      dartdocHtmlSuffix = '-outlined';
    } else if (id.endsWith('_monoline_filled')) {
      dartdocFamily = 'Monoline';
      dartdocHtmlSuffix = '-filled';
    } else {
      dartdocFamily = 'material';
      if (id.endsWith('_baseline')) {
        id = _removeLast(id, '_baseline');
        dartdocHtmlSuffix = '';
      } else if (id.endsWith('_outlined')) {
        dartdocHtmlSuffix = '-outlined';
      } else if (id.endsWith('_rounded')) {
        dartdocHtmlSuffix = '-round';
      } else if (id.endsWith('_sharp')) {
        dartdocHtmlSuffix = '-sharp';
      }
    }

    _generateShortId();
    _generateFlutterId();
  }

  late String id; // e.g. 5g, 5g_outlined, 5g_rounded, 5g_sharp
  late String shortId; // e.g. 5g
  late String flutterId; // e.g. five_g, five_g_outlined, five_g_rounded, five_g_sharp
  late String hexCodepoint; // e.g. e547
  late String dartdocFamily; // e.g. material
  late String dartdocHtmlSuffix = ''; // The suffix for the 'material-icons' HTML class.
  String fontFamily; // The IconData font family.
  List<String>
  possibleStyleSuffixes; // A list of possible suffixes e.g. _outlined, _monoline_filled.
  String className; // The containing class.

  String get name => shortId.replaceAll('_', ' ').trim();

  String get style =>
      dartdocHtmlSuffix == '' ? '' : ' (${dartdocHtmlSuffix.replaceFirst('-', '')})';

  String get dartDoc =>
      '<i class="material-icons$dartdocHtmlSuffix md-36">$shortId</i> &#x2014; $dartdocFamily icon named "$name"$style';

  String get usage => 'Icon($className.$flutterId),';

  bool get isMirroredInRTL {
    // Remove common suffixes (e.g. "_new" or "_alt") from the shortId.
    final String normalizedShortId = shortId.replaceAll(RegExp(r'_(new|alt|off|on)$'), '');
    return _iconsMirroredWhenRTL.any(
      (String shortIdMirroredWhenRTL) => normalizedShortId == shortIdMirroredWhenRTL,
    );
  }

  String get declaration =>
      "static const IconData $flutterId = IconData(0x$hexCodepoint, fontFamily: '$fontFamily'${isMirroredInRTL ? ', matchTextDirection: true' : ''});";

  String get fullDeclaration =>
      '''

  /// $dartDoc.
  $declaration
''';

  String platformAdaptiveDeclaration(String fullFlutterId, Icon iOSIcon) =>
      '''

  /// Platform-adaptive icon for $dartDoc and ${iOSIcon.dartDoc}.;
  IconData get $fullFlutterId => !_isCupertino() ? $className.$flutterId : $className.${iOSIcon.flutterId};
''';

  @override
  String toString() => id;

  /// Analogous to [String.compareTo]
  int _compareTo(Icon b) {
    if (shortId == b.shortId) {
      // Sort a regular icon before its variants.
      return id.length - b.id.length;
    }
    return shortId.compareTo(b.shortId);
  }

  static String _removeLast(String string, String toReplace) {
    return string.replaceAll(RegExp('$toReplace\$'), '');
  }

  /// See [shortId].
  void _generateShortId() {
    shortId = id;
    for (final String styleSuffix in possibleStyleSuffixes) {
      shortId = _removeLast(shortId, styleSuffix);
      if (shortId != id) {
        break;
      }
    }
  }

  /// See [flutterId].
  void _generateFlutterId() {
    flutterId = id;
    // Exact identifier rewrites.
    for (final MapEntry<String, String> rewritePair in _identifierExactRewrites.entries) {
      if (shortId == rewritePair.key) {
        flutterId = id.replaceFirst(rewritePair.key, _identifierExactRewrites[rewritePair.key]!);
      }
    }
    // Prefix identifier rewrites.
    for (final MapEntry<String, String> rewritePair in _identifierPrefixRewrites.entries) {
      if (id.startsWith(rewritePair.key)) {
        flutterId = id.replaceFirst(rewritePair.key, _identifierPrefixRewrites[rewritePair.key]!);
      }
    }

    // Prevent double underscores.
    flutterId = flutterId.replaceAll('__', '_');
  }
}
