// Copyright (c) 2016, 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 sourcemap.diff;

import 'package:compiler/src/io/source_file.dart';

import 'html_parts.dart';
import 'output_structure.dart';
import 'sourcemap_helper.dart';
import 'sourcemap_html_helper.dart';

enum DiffKind {
  UNMATCHED,
  MATCHING,
  IDENTICAL,
}

/// Id for an output column.
class DiffColumn {
  final String type;
  final int? index;

  const DiffColumn(this.type, [this.index]);

  @override
  int get hashCode => type.hashCode * 19 + index.hashCode * 23;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! DiffColumn) return false;
    return type == other.type && index == other.index;
  }

  @override
  String toString() => '$type${index ?? ''}';
}

/// A block of code in an output column.
abstract class DiffColumnBlock {
  void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context);
}

/// A block consisting of pure HTML parts.
class PartsColumnBlock extends DiffColumnBlock {
  final List<HtmlPart> parts;

  PartsColumnBlock(this.parts);

  @override
  void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) {
    if (parts.isNotEmpty) {
      for (HtmlPart part in parts) {
        part.printHtmlOn(htmlBuffer, context);
      }
    }
  }
}

/// A block consisting of line-per-line JavaScript and source mapped Dart code.
class CodeLinesColumnBlock extends DiffColumnBlock {
  final List<CodeLine> jsCodeLines;
  final Map<CodeLine, List<CodeLine>> jsToDartMap;

  CodeLinesColumnBlock(this.jsCodeLines, this.jsToDartMap);

  @override
  void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) {
    if (jsCodeLines.isNotEmpty) {
      htmlBuffer.write('<table style="width:100%">');
      for (CodeLine codeLine in jsCodeLines) {
        htmlBuffer.write('<tr><td class="${ClassNames.innerCell}">');
        codeLine.printHtmlOn(htmlBuffer, context);
        htmlBuffer.write('</td><td '
            'class="${ClassNames.innerCell} ${ClassNames.sourceMapped}">');
        List<CodeLine>? lines = jsToDartMap[codeLine];
        if (lines != null) {
          for (CodeLine line in lines) {
            line.printHtmlOn(htmlBuffer, context.from(includeAnnotation: (a) {
              CodeLineAnnotation annotation = a.data;
              return annotation.annotationType.isSourceMapped;
            }));
          }
        }
        htmlBuffer.write('</td></tr>');
      }
      htmlBuffer.write('</table>');
    }
  }
}

/// A list of columns that should align in output.
class DiffBlock {
  final DiffKind kind;
  final Map<DiffColumn, DiffColumnBlock> _columns =
      <DiffColumn, DiffColumnBlock>{};

  DiffBlock(this.kind);

  void addColumnBlock(DiffColumn column, DiffColumnBlock block) {
    _columns[column] = block;
  }

  Iterable<DiffColumn> get columns => _columns.keys;

  void printHtmlOn(
      DiffColumn column, StringBuffer htmlBuffer, HtmlPrintContext context) {
    DiffColumnBlock? block = _columns[column];
    if (block != null) {
      block.printHtmlOn(htmlBuffer, context);
    }
  }
}

bool _eq(a, b) => a == b;

/// Align the content of [list1] and [list2].
///
/// If provided, [range1] and [range2] aligned the subranges of [list1] and
/// [list2], otherwise the whole lists are aligned.
///
/// If provided, [match] determines the equality between members of [list1] and
/// [list2], otherwise `==` is used.
///
/// [handleSkew] is called when a subrange of one list is not found in the
/// other.
///
/// [handleMatched] is called when two indices match up.
///
/// [handleUnmatched] is called when two indices don't match up (none are found
/// in the other list).
void align(List list1, List list2,
    {Interval? range1,
    Interval? range2,
    bool match(a, b) = _eq,
    required void handleSkew(int listIndex, Interval range),
    required void handleMatched(List<int> indices),
    required void handleUnmatched(List<int> indices)}) {
  range1 ??= Interval(0, list1.length);
  range2 ??= Interval(0, list2.length);

  Interval? findInOther(List thisLines, Interval thisRange, List otherLines,
      Interval otherRange) {
    for (int index = otherRange.from; index < otherRange.to; index++) {
      if (match(thisLines[thisRange.from], otherLines[index])) {
        int offset = 1;
        while (thisRange.from + offset < thisRange.to &&
            otherRange.from + offset < otherRange.to &&
            match(thisLines[thisRange.from + offset],
                otherLines[otherRange.from + offset])) {
          offset++;
        }
        return Interval(index, index + offset);
      }
    }
    return null;
  }

  int start1 = range1.from;
  int end1 = range1.to;
  int start2 = range2.from;
  int end2 = range2.to;

  const int ALIGN1 = -1;
  const int UNMATCHED = 0;
  const int ALIGN2 = 1;

  while (start1 < end1 && start2 < end2) {
    if (match(list1[start1], list2[start2])) {
      handleMatched([start1++, start2++]);
    } else {
      Interval subrange1 = Interval(start1, end1);
      Interval subrange2 = Interval(start2, end2);
      Interval? element2inList1 =
          findInOther(list1, subrange1, list2, subrange2);
      Interval? element1inList2 =
          findInOther(list2, subrange2, list1, subrange1);
      int choice = 0;
      if (element2inList1 != null) {
        if (element1inList2 != null) {
          if (element1inList2.length > 1 && element2inList1.length > 1) {
            choice =
                element2inList1.from < element1inList2.from ? ALIGN2 : ALIGN1;
          } else if (element2inList1.length > 1) {
            choice = ALIGN2;
          } else if (element1inList2.length > 1) {
            choice = ALIGN1;
          } else {
            choice =
                element2inList1.from < element1inList2.from ? ALIGN2 : ALIGN1;
          }
        } else {
          choice = ALIGN2;
        }
      } else if (element1inList2 != null) {
        choice = ALIGN1;
      }
      switch (choice) {
        case ALIGN1:
          handleSkew(0, Interval(start1, element1inList2!.from));
          start1 = element1inList2.from;
          break;
        case ALIGN2:
          handleSkew(1, Interval(start2, element2inList1!.from));
          start2 = element2inList1.from;
          break;
        case UNMATCHED:
          handleUnmatched([start1++, start2++]);
          break;
      }
    }
  }
  if (start1 < end1) {
    handleSkew(0, Interval(start1, end1));
  }
  if (start2 < end2) {
    handleSkew(1, Interval(start2, end2));
  }
}

/// Create a list of blocks containing the diff of the two output [structures]
/// and the corresponding Dart code.
List<DiffBlock> createDiffBlocks(
    List<OutputStructure> structures, SourceFileManager sourceFileManager) {
  return DiffCreator(structures, sourceFileManager).computeBlocks();
}

class DiffCreator {
  final List<OutputStructure> structures;
  final SourceFileManager sourceFileManager;

  List<List<CodeLine>> inputLines;

  List<int> nextInputLine = [0, 0];

  List<DiffBlock> blocks = <DiffBlock>[];

  DiffCreator(List<OutputStructure> structures, this.sourceFileManager)
      : this.structures = structures,
        this.inputLines = structures.map((s) => s.lines).toList();

  /// Compute [CodeSource]s defined by [entities].
  Iterable<CodeSource> codeSourceFromEntities(Iterable<OutputEntity> entities) {
    Set<CodeSource> sources = Set<CodeSource>();
    for (OutputEntity entity in entities) {
      if (entity.codeSource != null) {
        sources.add(entity.codeSource!);
      }
    }
    return sources;
  }

  /// Create a block with the code from [codeSources]. The [CodeSource]s in
  /// [mainSources] are tagged as original code sources, the rest as inlined
  /// code sources.
  DiffColumnBlock codeLinesFromCodeSources(
      Iterable<CodeSource> mainSources, Iterable<CodeSource> codeSources) {
    List<HtmlPart> parts = <HtmlPart>[];
    for (CodeSource codeSource in codeSources) {
      //parts.addAll(codeLinesFromCodeSource(codeSource));
      String className = mainSources.contains(codeSource)
          ? ClassNames.originalDart
          : ClassNames.inlinedDart;
      parts.add(new TagPart('div',
          properties: {'class': className},
          content: codeLinesFromCodeSource(codeSource)));
    }
    return PartsColumnBlock(parts);
  }

  /// Adds all [CodeSource]s used in [dartCodeLines] to [codeSourceSet].
  void collectCodeSources(Set<CodeSource> codeSourceSet,
      Map<CodeLine, List<CodeLine>> dartCodeLines) {
    for (List<CodeLine> codeLines in dartCodeLines.values) {
      for (CodeLine dartCodeLine in codeLines) {
        if (dartCodeLine.lineAnnotation != null) {
          codeSourceSet.add(dartCodeLine.lineAnnotation);
        }
      }
    }
  }

  /// Checks that lines are added in sequence without gaps or duplicates.
  void checkLineInvariant(int index, Interval range) {
    int expectedLineNo = nextInputLine[index];
    if (range.from != expectedLineNo) {
      print('Expected line no $expectedLineNo, found ${range.from}');
      if (range.from < expectedLineNo) {
        print('Duplicate lines:');
        int i = range.from;
        while (i <= expectedLineNo) {
          print(inputLines[index][i++].code);
        }
      } else {
        print('Missing lines:');
        int i = expectedLineNo;
        while (i <= range.from) {
          print(inputLines[index][i++].code);
        }
      }
    }
    nextInputLine[index] = range.to;
  }

  /// Creates a block containing the code lines in [range] from input number
  /// [index]. If [codeSource] is provided, the block will contain a
  /// corresponding Dart code column.
  void handleSkew(int index, Interval range,
      [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) {
    if (range.isEmpty) return;

    Set<CodeSource> codeSources = Set<CodeSource>();
    codeSources.addAll(mainCodeSources);

    DiffBlock block = DiffBlock(DiffKind.UNMATCHED);
    checkLineInvariant(index, range);
    List<CodeLine> jsCodeLines =
        inputLines[index].sublist(range.from, range.to);
    Map<CodeLine, List<CodeLine>> dartCodeLines =
        dartCodeLinesFromJsCodeLines(jsCodeLines);
    block.addColumnBlock(new DiffColumn('js', index),
        CodeLinesColumnBlock(jsCodeLines, dartCodeLines));
    collectCodeSources(codeSources, dartCodeLines);

    if (codeSources.isNotEmpty) {
      block.addColumnBlock(const DiffColumn('dart'),
          codeLinesFromCodeSources(mainCodeSources, codeSources));
    }
    blocks.add(block);
  }

  /// Create a block containing the code lines in [ranges] from the
  /// corresponding JavaScript inputs. If [codeSource] is provided, the block
  /// will contain a corresponding Dart code column.
  void addLines(DiffKind kind, List<Interval> ranges,
      [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) {
    if (ranges.every((range) => range.isEmpty)) return;

    Set<CodeSource> codeSources = Set<CodeSource>();
    codeSources.addAll(mainCodeSources);

    DiffBlock block = DiffBlock(kind);
    for (int i = 0; i < ranges.length; i++) {
      checkLineInvariant(i, ranges[i]);
      List<CodeLine> jsCodeLines =
          inputLines[i].sublist(ranges[i].from, ranges[i].to);
      Map<CodeLine, List<CodeLine>> dartCodeLines =
          dartCodeLinesFromJsCodeLines(jsCodeLines);
      block.addColumnBlock(new DiffColumn('js', i),
          CodeLinesColumnBlock(jsCodeLines, dartCodeLines));
      collectCodeSources(codeSources, dartCodeLines);
    }
    if (codeSources.isNotEmpty) {
      block.addColumnBlock(const DiffColumn('dart'),
          codeLinesFromCodeSources(mainCodeSources, codeSources));
    }
    blocks.add(block);
  }

  /// Merge the code lines in [range1] and [range2] of the corresponding input.
  void addRaw(Interval range1, Interval range2) {
    if (range1.isEmpty && range2.isEmpty) return;

    match(a, b) => a.code == b.code;

    List<Interval>? currentMatchedIntervals;
    List<Interval>? currentUnmatchedIntervals;

    void flushMatching() {
      if (currentMatchedIntervals != null) {
        addLines(DiffKind.IDENTICAL, currentMatchedIntervals!);
      }
      currentMatchedIntervals = null;
    }

    void flushUnmatched() {
      if (currentUnmatchedIntervals != null) {
        addLines(DiffKind.UNMATCHED, currentUnmatchedIntervals!);
      }
      currentUnmatchedIntervals = null;
    }

    List<Interval> updateIntervals(List<Interval>? current, List<int> indices) {
      if (current == null) {
        return [
          Interval(indices[0], indices[0] + 1),
          Interval(indices[1], indices[1] + 1)
        ];
      } else {
        current[0] = Interval(current[0].from, indices[0] + 1);
        current[1] = Interval(current[1].from, indices[1] + 1);
        return current;
      }
    }

    align(inputLines[0], inputLines[1],
        range1: range1,
        range2: range2,
        match: match, handleSkew: (int listIndex, Interval range) {
      flushMatching();
      flushUnmatched();
      handleSkew(listIndex, range);
    }, handleMatched: (List<int> indices) {
      flushUnmatched();
      currentMatchedIntervals =
          updateIntervals(currentMatchedIntervals, indices);
    }, handleUnmatched: (List<int> indices) {
      flushMatching();
      currentUnmatchedIntervals =
          updateIntervals(currentUnmatchedIntervals, indices);
    });

    flushMatching();
    flushUnmatched();
  }

  /// Adds the top level blocks in [childRange] for structure [index].
  void addBlock(int index, Interval childRange) {
    addSkewedChildren(index, structures[index], childRange);
  }

  /// Adds the [entity] from structure [index]. If the [entity] supports child
  /// entities, these are process individually. Otherwise the lines from
  /// [entity] are added directly.
  void addSkewedEntity(int index, OutputEntity entity) {
    if (entity.canHaveChildren) {
      handleSkew(index, entity.header);
      addSkewedChildren(index, entity, Interval(0, entity.children.length));
      handleSkew(index, entity.footer);
    } else {
      handleSkew(index, entity.interval, codeSourceFromEntities([entity]));
    }
  }

  /// Adds the children of [parent] in [childRange] from structure [index].
  void addSkewedChildren(int index, OutputEntity parent, Interval childRange) {
    for (int i = childRange.from; i < childRange.to; i++) {
      addSkewedEntity(index, parent.getChild(i));
    }
  }

  /// Adds the members of the [classes] aligned.
  void addMatchingContainers(List<OutputEntity> classes) {
    addLines(DiffKind.MATCHING, classes.map((c) => c.header).toList());
    align(classes[0].children, classes[1].children,
        match: (a, b) => a.name == b.name,
        handleSkew: (int listIndex, Interval childRange) {
          addSkewedChildren(listIndex, classes[listIndex], childRange);
        },
        handleMatched: (List<int> indices) {
          List<OutputEntity> entities = [
            classes[0].getChild(indices[0]),
            classes[1].getChild(indices[1])
          ];
          if (entities.every((e) => e is Statics)) {
            addMatchingContainers(entities);
          } else {
            addLines(
                DiffKind.MATCHING,
                entities.map((e) => e.interval).toList(),
                codeSourceFromEntities(entities));
          }
        },
        handleUnmatched: (List<int> indices) {
          List<Interval> intervals = [
            classes[0].getChild(indices[0]).interval,
            classes[1].getChild(indices[1]).interval
          ];
          addLines(DiffKind.UNMATCHED, intervals);
        });
    addLines(DiffKind.MATCHING, classes.map((c) => c.footer).toList());
  }

  /// Adds the library blocks in [indices] from the corresponding
  /// [OutputStructure]s, aligning their content.
  void addMatchingBlocks(List<int> indices) {
    List<OutputEntity> blocks = [
      structures[0].getChild(indices[0]),
      structures[1].getChild(indices[1])
    ];

    addLines(DiffKind.MATCHING, blocks.map((b) => b.header).toList());
    align(blocks[0].children, blocks[1].children,
        match: (a, b) => a.name == b.name,
        handleSkew: (int listIndex, Interval childRange) {
          addSkewedChildren(listIndex, blocks[listIndex], childRange);
        },
        handleMatched: (List<int> indices) {
          List<OutputEntity> entities = [
            blocks[0].getChild(indices[0]),
            blocks[1].getChild(indices[1])
          ];
          if (entities.every((e) => e is LibraryClass)) {
            addMatchingContainers(entities);
          } else {
            addLines(
                DiffKind.MATCHING,
                entities.map((e) => e.interval).toList(),
                codeSourceFromEntities(entities));
          }
        },
        handleUnmatched: (List<int> indices) {
          List<Interval> intervals = [
            blocks[0].getChild(indices[0]).interval,
            blocks[1].getChild(indices[1]).interval
          ];
          addLines(DiffKind.UNMATCHED, intervals);
        });
    addLines(DiffKind.MATCHING, blocks.map((b) => b.footer).toList());
  }

  /// Adds the lines of the blocks in [indices] from the corresponding
  /// [OutputStructure]s.
  void addUnmatchedBlocks(List<int> indices) {
    List<OutputEntity> blocks = [
      structures[0].getChild(indices[0]),
      structures[1].getChild(indices[1])
    ];
    addLines(DiffKind.UNMATCHED, [blocks[0].interval, blocks[1].interval]);
  }

  /// Computes the diff blocks for [OutputStructure]s.
  List<DiffBlock> computeBlocks() {
    addRaw(structures[0].header, structures[1].header);

    align(structures[0].children, structures[1].children,
        match: (a, b) => a.name == b.name,
        handleSkew: addBlock,
        handleMatched: addMatchingBlocks,
        handleUnmatched: addUnmatchedBlocks);

    addRaw(structures[0].footer, structures[1].footer);

    return blocks;
  }

  /// Creates html lines for code lines in [codeSource]. The [sourceFileManager]
  /// is used to read that text from the source URIs.
  List<HtmlPart> codeLinesFromCodeSource(CodeSource codeSource) {
    List<HtmlPart> lines = <HtmlPart>[];
    SourceFile sourceFile = sourceFileManager.getSourceFile(codeSource.uri)!;
    String elementName = codeSource.name;
    HtmlLine line = HtmlLine();
    line.htmlParts.add(new ConstHtmlPart('<span class="comment">'));
    line.htmlParts.add(new HtmlText('${elementName}: ${sourceFile.filename}'));
    line.htmlParts.add(new ConstHtmlPart('</span>'));
    lines.add(line);
    if (codeSource.begin != null) {
      int startLine = sourceFile.getLocation(codeSource.begin!).line - 1;
      int endLine = sourceFile.getLocation(codeSource.end!).line;
      for (CodeLine codeLine in convertAnnotatedCodeToCodeLines(
          sourceFile.slowText(), const <Annotation>[],
          startLine: startLine, endLine: endLine)) {
        codeLine.lineAnnotation = codeSource;
        lines.add(codeLine);
      }
    }
    return lines;
  }

  /// Creates a map from JavaScript [CodeLine]s in [jsCodeLines] to the Dart
  /// [CodeLine]s references in the source information.
  Map<CodeLine, List<CodeLine>> dartCodeLinesFromJsCodeLines(
      List<CodeLine> jsCodeLines) {
    Map<CodeLine, Interval> codeLineInterval = <CodeLine, Interval>{};
    Map<CodeLine, List<CodeLine>> jsToDartMap = <CodeLine, List<CodeLine>>{};
    List<Annotation> annotations = <Annotation>[];
    Uri? currentUri;
    late Interval interval;

    Map<Uri, Set<CodeSource>> codeSourceMap = <Uri, Set<CodeSource>>{};

    for (CodeLine jsCodeLine in jsCodeLines) {
      for (Annotation annotation in jsCodeLine.annotations) {
        CodeLineAnnotation codeLineAnnotation = annotation.data;
        for (CodeSource codeSource in codeLineAnnotation.codeSources) {
          codeSourceMap
              .putIfAbsent(codeSource.uri, () => Set<CodeSource>())
              .add(codeSource);
        }
      }
    }

    void flush() {
      if (currentUri == null) return;

      Set<CodeSource>? codeSources = codeSourceMap[currentUri];
      SourceFile sourceFile = sourceFileManager.getSourceFile(currentUri)!;
      List<CodeLine> annotatedDartCodeLines = convertAnnotatedCodeToCodeLines(
          sourceFile.slowText(), annotations,
          startLine: interval.from, endLine: interval.to, uri: currentUri);
      if (codeSources != null) {
        CodeSource? currentCodeSource;
        late Interval currentLineInterval;
        for (CodeLine dartCodeLine in annotatedDartCodeLines) {
          if (currentCodeSource == null ||
              !currentLineInterval.contains(dartCodeLine.lineNo)) {
            currentCodeSource = null;
            for (CodeSource codeSource in codeSources) {
              Interval interval = Interval(
                  sourceFile.getLocation(codeSource.begin!).line - 1,
                  sourceFile.getLocation(codeSource.end!).line);
              if (interval.contains(dartCodeLine.lineNo)) {
                currentCodeSource = codeSource;
                currentLineInterval = interval;
                break;
              }
            }
          }
          if (currentCodeSource != null) {
            dartCodeLine.lineAnnotation = currentCodeSource;
          }
        }
      }

      int index = 0;
      for (CodeLine jsCodeLine in codeLineInterval.keys) {
        List<CodeLine> dartCodeLines =
            jsToDartMap.putIfAbsent(jsCodeLine, () => <CodeLine>[]);
        if (dartCodeLines.isEmpty && index < annotatedDartCodeLines.length) {
          dartCodeLines.add(annotatedDartCodeLines[index++]);
        }
      }
      while (index < annotatedDartCodeLines.length) {
        jsToDartMap[codeLineInterval.keys.last]!
            .add(annotatedDartCodeLines[index++]);
      }

      currentUri = null;
    }

    void restart(CodeLine codeLine, CodeLocation codeLocation, int line) {
      flush();

      currentUri = codeLocation.uri;
      interval = Interval(line, line + 1);
      annotations = <Annotation>[];
      codeLineInterval.clear();
      codeLineInterval[codeLine] = interval;
    }

    for (CodeLine jsCodeLine in jsCodeLines) {
      for (Annotation annotation in jsCodeLine.annotations) {
        CodeLineAnnotation codeLineAnnotation = annotation.data;

        for (CodeLocation location in codeLineAnnotation.codeLocations) {
          SourceFile sourceFile =
              sourceFileManager.getSourceFile(location.uri)!;
          int line = sourceFile.getLocation(location.offset).line - 1;
          if (currentUri != location.uri) {
            restart(jsCodeLine, location, line);
          } else if (interval.inWindow(line, windowSize: 2)) {
            interval = interval.include(line);
            codeLineInterval[jsCodeLine] = interval;
          } else {
            restart(jsCodeLine, location, line);
          }

          annotations.add(new Annotation(codeLineAnnotation.annotationType,
              location.offset, 'id=${codeLineAnnotation.annotationId}',
              data: codeLineAnnotation));
        }
      }
    }
    flush();
    return jsToDartMap;
  }
}

const DiffColumn column_js0 = const DiffColumn('js', 0);
const DiffColumn column_js1 = const DiffColumn('js', 1);
const DiffColumn column_dart = const DiffColumn('dart');

class ClassNames {
  static String column(DiffColumn column) => 'column_${column}';
  static String identical(bool alternate) =>
      'identical${alternate ? '1' : '2'}';
  static String corresponding(bool alternate) =>
      'corresponding${alternate ? '1' : '2'}';

  static const String buttons = 'buttons';
  static const String comment = 'comment';
  static const String header = 'header';
  static const String headerTable = 'header_table';
  static const String headerColumn = 'header_column';
  static const String legend = 'legend';
  static const String table = 'table';

  static const String cell = 'cell';
  static const String innerCell = 'inner_cell';

  static const String originalDart = 'main_dart';
  static const String inlinedDart = 'inlined_dart';

  static const String line = 'line';
  static const String lineNumber = 'line_number';
  static String colored(int index) => 'colored${index}';

  static const String withSourceInfo = 'with_source_info';
  static const String withoutSourceInfo = 'without_source_info';
  static const String additionalSourceInfo = 'additional_source_info';
  static const String unusedSourceInfo = 'unused_source_info';

  static const String sourceMapped = 'source_mapped';
  static const String sourceMapping = 'source_mapping';
  static String sourceMappingIndex(int index) => 'source_mapping${index}';

  static const String markers = 'markers';
  static const String marker = 'marker';
}

enum AnnotationType {
  withSourceInfo(ClassNames.withSourceInfo, true),
  withoutSourceInfo(ClassNames.withoutSourceInfo, false),
  additionalSourceInfo(ClassNames.additionalSourceInfo, true),
  unusedSourceInfo(ClassNames.unusedSourceInfo, false),
  ;

  final String className;
  final bool isSourceMapped;

  const AnnotationType(this.className, this.isSourceMapped);
}

class CodeLineAnnotation {
  final int annotationId;
  final AnnotationType annotationType;
  final List<CodeLocation> codeLocations;
  final List<CodeSource> codeSources;
  final String? stepInfo;
  int? sourceMappingIndex;

  CodeLineAnnotation(
      {required this.annotationId,
      required this.annotationType,
      required this.codeLocations,
      required this.codeSources,
      this.stepInfo,
      this.sourceMappingIndex});

  Map toJson(JsonStrategy strategy) {
    return {
      'annotationId': annotationId,
      'annotationType': annotationType.index,
      'codeLocations': codeLocations.map((l) => l.toJson(strategy)).toList(),
      'codeSources': codeSources.map((c) => c.toJson()).toList(),
      'stepInfo': stepInfo,
      'sourceMappingIndex': sourceMappingIndex,
    };
  }

  static fromJson(Map json, JsonStrategy strategy) {
    return CodeLineAnnotation(
        annotationId: json['id'],
        annotationType: AnnotationType.values[json['annotationType']],
        codeLocations: json['codeLocations']
            .map((j) => CodeLocation.fromJson(j, strategy))
            .toList(),
        codeSources:
            json['codeSources'].map((j) => CodeSource.fromJson(j)).toList(),
        stepInfo: json['stepInfo'],
        sourceMappingIndex: json['sourceMappingIndex']);
  }
}
