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
  visitAll(AllInfo info) {
    throw StateError('should not diff AllInfo');
  }

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

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

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

  @override
  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
  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
  visitClassType(ClassTypeInfo info) {
    var other = _other as ClassTypeInfo;
    _checkSize(info, other);
    _checkDeferredStatus(info, other);
  }

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

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

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

  @override
  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]!));
      }
    }
  }
}
