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

library tracer;

import 'package:kernel/text/indentation.dart' show Indentation;

import '../compiler_api.dart' as api;
import 'js_model/js_world.dart' show JClosedWorld;
import 'options.dart' show CompilerOptions;
import 'ssa/nodes.dart' as ssa show HGraph;
import 'ssa/tracer.dart' show HTracer;

String? TRACE_FILTER_PATTERN_FOR_TEST;

/// Dumps the intermediate representation after each phase in a format
/// readable by IR Hydra.
class Tracer extends TracerUtil {
  final JClosedWorld closedWorld;
  bool traceActive = false;
  @override
  final api.OutputSink? output;
  final RegExp? traceFilter;

  Tracer._(this.closedWorld, this.traceFilter, this.output);

  factory Tracer(JClosedWorld closedWorld, CompilerOptions options,
      api.CompilerOutput compilerOutput) {
    String? pattern = options.dumpSsaPattern ?? TRACE_FILTER_PATTERN_FOR_TEST;
    if (pattern == null) return Tracer._(closedWorld, null, null);
    var traceFilter = RegExp(pattern);
    var output =
        compilerOutput.createOutputSink('', 'cfg', api.OutputType.debug);
    return Tracer._(closedWorld, traceFilter, output);
  }

  bool get isEnabled => traceFilter != null;

  void traceCompilation(String methodName) {
    if (!isEnabled) return;
    traceActive = traceFilter!.hasMatch(methodName);
    if (!traceActive) return;
    tag("compilation", () {
      printProperty("name", methodName);
      printProperty("method", methodName);
      printProperty("date", DateTime.now().millisecondsSinceEpoch);
    });
  }

  void traceGraph(String name, var irObject) {
    if (!traceActive) return;
    if (irObject is ssa.HGraph) {
      HTracer(output!, closedWorld).traceGraph(name, irObject);
    }
  }

  void traceJavaScriptText(String name, String Function() getText) {
    if (!traceActive) return;
    HTracer(output!, closedWorld).traceJavaScriptText(name, getText());
  }

  void close() {
    if (output != null) {
      output!.close();
    }
  }
}

abstract class TracerUtil {
  api.OutputSink? get output;
  final Indentation _ind = Indentation();

  void tag(String tagName, Function f) {
    println("begin_$tagName");
    _ind.indentBlock(f);
    println("end_$tagName");
  }

  void println(String string) {
    addIndent();
    add(string);
    add("\n");
  }

  void printEmptyProperty(String propertyName) {
    println(propertyName);
  }

  String formatPrty(x) {
    if (x is num) {
      return '${x}';
    } else if (x is String) {
      return '"${x}"';
    } else if (x is Iterable) {
      return x.map((s) => formatPrty(s)).join(' ');
    } else {
      throw "invalid property type: ${x}";
    }
  }

  void printProperty(String propertyName, value) {
    println("$propertyName ${formatPrty(value)}");
  }

  void add(String string) {
    output!.add(string);
  }

  void addIndent() {
    add(_ind.indentation);
  }
}
