import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/util.dart';

class Diff {
  final BasicInfo info;
  final DiffKind kind;
  Diff(this.info, this.kind);
}

enum DiffKind { add, remove, size, deferred }

class RemoveDiff extends Diff {
  RemoveDiff(BasicInfo info) : super(info, DiffKind.remove);
}

class AddDiff extends Diff {
  AddDiff(BasicInfo info) : super(info, DiffKind.add);
}

class SizeDiff extends Diff {
  final int sizeDifference;
  SizeDiff(BasicInfo info, this.sizeDifference) : super(info, DiffKind.size);
}

class DeferredStatusDiff extends Diff {
  final bool wasDeferredBefore;
  DeferredStatusDiff(BasicInfo info, this.wasDeferredBefore)
    : super(info, DiffKind.deferred);
}

List<Diff> diff(AllInfo oldInfo, AllInfo newInfo) {
  var differ = _InfoDiffer(oldInfo, newInfo);
  differ.diff();
  return differ.diffs;
}

class _InfoDiffer extends InfoVisitor<void> {
  final AllInfo _old;
  final AllInfo _new;

  BasicInfo? _other;

  List<Diff> diffs = <Diff>[];

  _InfoDiffer(this._old, this._new);

  void diff() {
    _diffList(_old.libraries, _new.libraries);
  }

  @override
  void visitAll(AllInfo info) {
    throw StateError('should not diff AllInfo');
  }

  @override
  void visitProgram(ProgramInfo info) {
    throw StateError('should not diff ProgramInfo');
  }

  @override
  void visitOutput(OutputUnitInfo info) {
    throw StateError('should not diff OutputUnitInfo');
  }

  // TODO(het): diff constants
  @override
  void visitConstant(ConstantInfo info) {
    throw StateError('should not diff ConstantInfo');
  }

  @override
  void visitLibrary(LibraryInfo info) {
    var other = _other as LibraryInfo;
    _checkSize(info, other);
    _diffList(info.topLevelVariables, other.topLevelVariables);
    _diffList(info.topLevelFunctions, other.topLevelFunctions);
    _diffList(info.classes, other.classes);
  }

  @override
  void visitClass(ClassInfo info) {
    var other = _other as ClassInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
    _diffList(info.fields, other.fields);
    _diffList(info.functions, other.functions);
  }

  @override
  void visitClassType(ClassTypeInfo info) {
    var other = _other as ClassTypeInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
  }

  @override
  void visitClosure(ClosureInfo info) {
    var other = _other as ClosureInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
    _diffList([info.function], [other.function]);
  }

  @override
  void visitField(FieldInfo info) {
    var other = _other as FieldInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
    _diffList(info.closures, other.closures);
  }

  @override
  void visitFunction(FunctionInfo info) {
    var other = _other as FunctionInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
    _diffList(info.closures, other.closures);
  }

  @override
  void visitTypedef(TypedefInfo info) {
    var other = _other as TypedefInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
  }

  void _checkSize(BasicInfo info, BasicInfo other) {
    if (info.size != other.size) {
      diffs.add(SizeDiff(info, other.size - info.size));
    }
  }

  void _checkDeferredStatus(BasicInfo oldInfo, BasicInfo newInfo) {
    var oldIsDeferred = _isDeferred(oldInfo);
    var newIsDeferred = _isDeferred(newInfo);
    if (oldIsDeferred != newIsDeferred) {
      diffs.add(DeferredStatusDiff(oldInfo, oldIsDeferred));
    }
  }

  bool _isDeferred(BasicInfo info) {
    var outputUnit = info.outputUnit!;
    return outputUnit.name.isNotEmpty && outputUnit.name != 'main';
  }

  void _diffList(List<BasicInfo> oldInfos, List<BasicInfo> newInfos) {
    var oldNames = <String, BasicInfo>{};
    var newNames = <String, BasicInfo>{};
    for (var oldInfo in oldInfos) {
      oldNames[longName(oldInfo, useLibraryUri: true)] = oldInfo;
    }
    for (var newInfo in newInfos) {
      newNames[longName(newInfo, useLibraryUri: true)] = newInfo;
    }
    for (var oldName in oldNames.keys) {
      if (newNames[oldName] == null) {
        diffs.add(RemoveDiff(oldNames[oldName]!));
      } else {
        _other = newNames[oldName];
        oldNames[oldName]!.accept(this);
      }
    }
    for (var newName in newNames.keys) {
      if (oldNames[newName] == null) {
        diffs.add(AddDiff(newNames[newName]!));
      }
    }
  }
}
