// Copyright (c) 2023, 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.

import 'dart:convert';

import 'package:analyzer_testing/package_root.dart' as pkg_root;
import 'package:analyzer_utilities/tools.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart';

Future<void> main() async {
  await GeneratedContent.generateAll(pkg_root.packageRoot, allTargets);
}

final allTargets = [
  GeneratedFile(
    'analyzer/lib/src/wolf/ir/ir.g.dart',
    (pkgRoot) async => _IrGenerator().run(),
  ),
];

final analyzerPkgPath = normalize(join(pkg_root.packageRoot, 'analyzer'));

final _instructions = _Instructions();

sealed class _Encoding {
  final String type;

  const _Encoding(this.type);

  @override
  int get hashCode => type.hashCode;

  @override
  operator ==(other) => other is _Encoding && type == other.type;

  _Parameter call(String name) => _Parameter._(name, this);

  String decode(String value);

  String encode(String value);

  String stringInterpolation(String value);
}

class _Instruction {
  final String name;
  final List<_Parameter> parameters;
  final int parameterShapeId;

  _Instruction(this.name, this.parameters, this.parameterShapeId);

  String get className => '_${name.capitalized}Instruction';

  String get signature {
    var parametersString = [
      for (var p in parameters) '${p.encoding.type} ${p.name}',
    ].join(', ');
    return '$name($parametersString)';
  }
}

class _Instructions {
  late final sorted = all.toList()..sort((a, b) => a.name.compareTo(b.name));

  final all = <_Instruction>[];

  final encodings = <_NontrivialEncoding>[];

  final parameterShapeMap = <_ParameterShape, int>{};

  _Instructions() {
    // Encodings
    var callDescriptor = encoding('CallDescriptorRef');
    var argumentNames = encoding('ArgumentNamesRef');
    var functionFlags = encoding(
      'FunctionFlags',
      fieldName: '_flags',
      constructorName: '_',
    );
    var literal = encoding('LiteralRef');
    var stackIndices = encoding('StackIndicesRef');
    var type = encoding('TypeRef');
    const uint = _TrivialEncoding('int');

    // Local variable access
    _addInstruction('alloc', [uint('count')]);
    _addInstruction('release', [uint('count')]);
    _addInstruction('readLocal', [uint('localIndex')]);
    _addInstruction('writeLocal', [uint('localIndex')]);
    // Primitive operations
    _addInstruction('literal', [literal('value')]);
    _addInstruction('identical', []);
    _addInstruction('eq', []);
    _addInstruction('not', []);
    _addInstruction('concat', [uint('count')]);
    _addInstruction('is_', [type('type')]);
    // Stack manipulation
    _addInstruction('drop', []);
    _addInstruction('dup', []);
    _addInstruction('shuffle', [
      uint('popCount'),
      stackIndices('stackIndices'),
    ]);
    // Flow control
    _addInstruction('block', [uint('inputCount'), uint('outputCount')]);
    _addInstruction('loop', [uint('inputCount')]);
    _addInstruction('function', [type('type'), functionFlags('flags')]);
    _addInstruction('end', []);
    _addInstruction('br', [uint('nesting')]);
    _addInstruction('brIf', [uint('nesting')]);
    _addInstruction('await_', []);
    _addInstruction('yield_', []);
    // Invocations and tearoffs
    _addInstruction('call', [
      callDescriptor('callDescriptor'),
      argumentNames('argumentNames'),
    ]);
  }

  _NontrivialEncoding encoding(
    String type, {
    String fieldName = 'index',
    String constructorName = '',
  }) {
    var encoding = _NontrivialEncoding(
      type,
      fieldName: fieldName,
      constructorName: constructorName,
    );
    encodings.add(encoding);
    return encoding;
  }

  void _addInstruction(String name, List<_Parameter> parameters) {
    var parameterShapeId = parameterShapeMap.putIfAbsent(
      _ParameterShape(parameters),
      () => parameterShapeMap.length,
    );
    all.add(_Instruction(name, parameters, parameterShapeId));
  }
}

class _IrGenerator {
  final _substringsToOutput = <String>[];

  void blankLine() {
    output('\n');
  }

  void output(String s) {
    _substringsToOutput.add(s);
  }

  void outputIRToStringMixin() {
    output('''
mixin IRToStringMixin implements RawIRContainerInterface {
  String instructionToString(int address) {
    switch (opcodeAt(address)) {
''');
    _instructions.all.forEachSeparated(blankLine, (instruction) {
      var opcode = 'Opcode.${instruction.name}';
      var interpolation = instruction.name.demangled;
      if (instruction.parameters.isNotEmpty) {
        var interpolationParts = <String>[];
        for (var p in instruction.parameters) {
          interpolationParts.add(
            p.encoding.stringInterpolation(
              '$opcode.decode${p.name.capitalized}(this, address)',
            ),
          );
        }
        interpolation += '(${interpolationParts.join(', ')})';
      }
      output('''
      case $opcode:
        return '$interpolation';
''');
    });
    output('''
      default:
        return '???';
    }
  }
}

''');
  }

  void outputOpcode() {
    output('''
// TODO(paulberry): when extension types are supported, make this an extension
// type, as well as all the `_ParameterShape` classes.
class Opcode {
  final int index;

  const Opcode._(this.index);

''');
    _instructions.all.forEachIndexed((i, instruction) {
      var shapeId = instruction.parameterShapeId;
      output(
        '  static const ${instruction.name} = '
        '_ParameterShape$shapeId._(${i++});\n',
      );
    });
    output('''

  String describe() => opcodeNameTable[index];

  static const opcodeNameTable = [
''');
    _instructions.all.forEachIndexed((i, instruction) {
      output('    ${json.encode(instruction.name.demangled)},');
    });
    output('''
  ];
}

''');
  }

  void outputParameterShapes() {
    _instructions.parameterShapeMap.forEach((parameterShape, id) {
      output('''
class _ParameterShape$id extends Opcode {
  const _ParameterShape$id._(super.index) : super._();
''');
      var i = 0;
      for (var parameter in parameterShape._parameters) {
        var returnType = parameter.encoding.type;
        var name = 'decode${parameter.name.capitalized}';
        var value = parameter.encoding.decode('ir._params${i++}[address]');
        output('''

  $returnType $name(RawIRContainerInterface ir, int address) {
    assert(ir.opcodeAt(address).index == index);
    return $value;
  }
''');
      }
      output('''
}

''');
    });
  }

  void outputRawIRWriterMixin() {
    output('''
mixin _RawIRWriterMixin implements _RawIRWriterMixinInterface {
''');
    _instructions.sorted.forEachSeparated(blankLine, (instruction) {
      output('''
  void ${instruction.signature} {
    _opcodes.add(Opcode.${instruction.name});
''');
      var i = 0;
      for (var p in instruction.parameters) {
        output('    _params${i++}.add(${p.encoding.encode(p.name)});\n');
      }
      while (i < 2) {
        output('    _params${i++}.add(0);\n');
      }
      output('''
  }
''');
    });
    output('}\n\n');
  }

  String run() {
    output(r'''
// Copyright (c) 2023, 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.

// THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'pkg/analyzer/tool/wolf/generate.dart' and run
// 'dart run pkg/analyzer/tool/wolf/generate.dart' to update.

part of 'ir.dart';

''');
    outputRawIRWriterMixin();
    outputIRToStringMixin();
    outputParameterShapes();
    outputOpcode();
    return _substringsToOutput.join();
  }
}

class _NontrivialEncoding extends _Encoding {
  final String fieldName;
  final String constructorName;

  _NontrivialEncoding(
    super.type, {
    required this.fieldName,
    required this.constructorName,
  });

  @override
  String decode(String value) =>
      '$type${constructorName.isEmpty ? '' : '.$constructorName'}($value)';

  @override
  String encode(String value) => '$value.$fieldName';

  @override
  String stringInterpolation(String value) =>
      '\${${type.uncapitalized}ToString($value)}';
}

class _Parameter {
  final String name;
  final _Encoding encoding;

  _Parameter._(this.name, this.encoding);

  String get fieldName => '_$name';

  @override
  int get hashCode => Object.hash(name, encoding);

  @override
  bool operator ==(other) =>
      other is _Parameter && name == other.name && encoding == other.encoding;
}

class _ParameterShape {
  final List<_Parameter> _parameters;

  _ParameterShape(this._parameters);

  @override
  int get hashCode => Object.hashAll(_parameters);

  @override
  bool operator ==(other) {
    if (other is! _ParameterShape ||
        _parameters.length != other._parameters.length) {
      return false;
    }
    for (var i = 0; i < _parameters.length; i++) {
      if (_parameters[i] != other._parameters[i]) return false;
    }
    return true;
  }
}

class _TrivialEncoding extends _Encoding {
  const _TrivialEncoding(super.type);

  @override
  String decode(String value) => value;

  @override
  String encode(String value) => value;

  @override
  String stringInterpolation(String value) => '\${$value}';
}

extension<T> on List<T> {
  void forEachSeparated(void Function() separator, void Function(T) callback) {
    void Function()? nextSeparator;
    for (var item in this) {
      nextSeparator?.call();
      callback(item);
      nextSeparator = separator;
    }
  }
}

extension on String {
  String get capitalized => '${this[0].toUpperCase()}${substring(1)}';

  String get demangled => endsWith('_') ? substring(0, length - 1) : this;

  String get uncapitalized => '${this[0].toLowerCase()}${substring(1)}';
}
