// Copyright (c) 2018, 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 'package:expect/expect.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/deferred_load.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_backend/namer.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js/js.dart' as js;

ClassEntity lookupClass(JElementEnvironment elementEnvironment, String name) {
  ClassEntity cls =
      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
  Expect.isNotNull(cls, "No class '$name' found in the main library.");
  return cls;
}

MemberEntity lookupMember(JElementEnvironment elementEnvironment, String name) {
  MemberEntity member;
  int dotIndex = name.indexOf('.');
  if (dotIndex != -1) {
    String className = name.substring(0, dotIndex);
    name = name.substring(dotIndex + 1);
    ClassEntity cls = elementEnvironment.lookupClass(
        elementEnvironment.mainLibrary, className);
    Expect.isNotNull(cls, "No class '$className' found in the main library.");
    member = elementEnvironment.lookupClassMember(cls, name);
    member ??= elementEnvironment.lookupConstructor(cls, name);
    Expect.isNotNull(member, "No member '$name' found in $cls");
  } else {
    member = elementEnvironment.lookupLibraryMember(
        elementEnvironment.mainLibrary, name);
    Expect.isNotNull(member, "No member '$name' found in the main library.");
  }
  return member;
}

class ProgramLookup {
  final Program program;
  final Namer namer;

  ProgramLookup(Compiler compiler)
      : this.program = compiler.backend.emitterTask.emitter.programForTesting,
        this.namer = compiler.backend.namerForTesting;

  Fragment getFragment(OutputUnit outputUnit) {
    for (Fragment fragment in program.fragments) {
      if (fragment.outputUnit == outputUnit) {
        return fragment;
      }
    }
    return null;
  }

  Map<LibraryEntity, LibraryData> libraryMap;

  LibraryData getLibraryData(LibraryEntity element) {
    if (libraryMap == null) {
      libraryMap = <LibraryEntity, LibraryData>{};
      for (Fragment fragment in program.fragments) {
        for (Library library in fragment.libraries) {
          assert(!libraryMap.containsKey(library.element));
          libraryMap[library.element] = new LibraryData(library, fragment);
        }
      }
    }
    return libraryMap[element];
  }

  Library getLibrary(LibraryEntity element) {
    return getLibraryData(element)?.library;
  }

  ClassData getClassData(ClassEntity element) {
    return getLibraryData(element.library)?.getClassData(element);
  }

  Class getClass(ClassEntity element) {
    return getClassData(element)?.cls;
  }

  Method getMethod(FunctionEntity function) {
    if (function.enclosingClass != null) {
      return getClassData(function.enclosingClass)?.getMethod(function);
    } else {
      return getLibraryData(function.library)?.getMethod(function);
    }
  }

  Field getField(FieldEntity field) {
    if (field.enclosingClass != null) {
      return getClassData(field.enclosingClass)?.getField(field);
    } else {
      return getLibraryData(field.library)?.getField(field);
    }
  }

  StaticField getStaticField(FieldEntity field) {
    if (field.enclosingClass != null) {
      return getClassData(field.enclosingClass)?.getStaticField(field);
    } else {
      return getLibraryData(field.library)?.getStaticField(field);
    }
  }
}

class LibraryData {
  final Library library;
  Map<ClassEntity, ClassData> _classMap = {};
  Map<FunctionEntity, StaticMethod> _methodMap = {};
  Map<FieldEntity, Field> _fieldMap = {};
  Map<FieldEntity, StaticField> _staticFieldMap = {};

  LibraryData(this.library, Fragment fragment) {
    for (Class cls in library.classes) {
      assert(!_classMap.containsKey(cls.element));
      _classMap[cls.element] = new ClassData(cls);
    }
    for (StaticMethod method in library.statics) {
      ClassEntity enclosingClass = method.element?.enclosingClass;
      if (enclosingClass != null) {
        ClassData data =
            _classMap.putIfAbsent(enclosingClass, () => new ClassData(null));
        assert(!data._methodMap.containsKey(method.element));
        data._methodMap[method.element] = method;
      } else if (method.element != null) {
        assert(!_methodMap.containsKey(method.element));
        _methodMap[method.element] = method;
      }
    }

    void addField(Field field) {
      ClassEntity enclosingClass = field.element?.enclosingClass;
      if (enclosingClass != null) {
        ClassData data =
            _classMap.putIfAbsent(enclosingClass, () => new ClassData(null));
        assert(!data._fieldMap.containsKey(field.element));
        data._fieldMap[field.element] = field;
      } else if (field.element != null) {
        assert(!_fieldMap.containsKey(field.element));
        _fieldMap[field.element] = field;
      }
    }

    for (Field field in library.staticFieldsForReflection) {
      addField(field);
    }

    void addStaticField(StaticField field) {
      ClassEntity enclosingClass = field.element?.enclosingClass;
      if (enclosingClass != null) {
        ClassData data =
            _classMap.putIfAbsent(enclosingClass, () => new ClassData(null));
        assert(!data._fieldMap.containsKey(field.element));
        data._staticFieldMap[field.element] = field;
      } else if (field.element != null) {
        assert(!_fieldMap.containsKey(field.element));
        _staticFieldMap[field.element] = field;
      }
    }

    for (StaticField field in fragment.staticNonFinalFields) {
      addStaticField(field);
    }
    for (StaticField field in fragment.staticLazilyInitializedFields) {
      addStaticField(field);
    }
  }

  ClassData getClassData(ClassEntity element) {
    return _classMap[element];
  }

  StaticMethod getMethod(FunctionEntity function) {
    return _methodMap[function];
  }

  Field getField(FieldEntity field) {
    return _fieldMap[field];
  }

  StaticField getStaticField(FieldEntity field) {
    return _staticFieldMap[field];
  }

  @override
  String toString() => 'LibraryData(library=$library,_classMap=$_classMap,'
      '_methodMap=$_methodMap,_fieldMap=$_fieldMap)';
}

class ClassData {
  final Class cls;
  Map<FunctionEntity, Method> _methodMap = {};
  Map<FieldEntity, Field> _fieldMap = {};
  Map<FieldEntity, StaticField> _staticFieldMap = {};
  Map<FieldEntity, StubMethod> _checkedSetterMap = {};

  ClassData(this.cls) {
    if (cls != null) {
      for (Method method in cls.methods) {
        assert(!_methodMap.containsKey(method.element));
        _methodMap[method.element] = method;
      }
      for (Field field in cls.fields) {
        assert(!_fieldMap.containsKey(field.element));
        _fieldMap[field.element] = field;
      }
      for (StubMethod checkedSetter in cls.checkedSetters) {
        assert(!_checkedSetterMap.containsKey(checkedSetter.element));
        _checkedSetterMap[checkedSetter.element] = checkedSetter;
      }
    }
  }

  Method getMethod(FunctionEntity function) {
    return _methodMap[function];
  }

  Field getField(FieldEntity field) {
    return _fieldMap[field];
  }

  StaticField getStaticField(FieldEntity field) {
    return _staticFieldMap[field];
  }

  StubMethod getCheckedSetter(FieldEntity field) {
    return _checkedSetterMap[field];
  }

  @override
  String toString() => 'ClassData(cls=$cls,'
      '_methodMap=$_methodMap,_fieldMap=$_fieldMap)';
}

void forEachNode(js.Node root,
    {void Function(js.Call) onCall,
    void Function(js.PropertyAccess) onPropertyAccess,
    void Function(js.Assignment) onAssignment,
    void Function(js.Switch) onSwitch}) {
  CallbackVisitor visitor = new CallbackVisitor(
      onCall: onCall,
      onPropertyAccess: onPropertyAccess,
      onAssignment: onAssignment,
      onSwitch: onSwitch);
  root.accept(visitor);
}

class CallbackVisitor extends js.BaseVisitor {
  final void Function(js.Call) onCall;
  final void Function(js.PropertyAccess) onPropertyAccess;
  final void Function(js.Assignment) onAssignment;
  final void Function(js.Switch) onSwitch;

  CallbackVisitor(
      {this.onCall, this.onPropertyAccess, this.onAssignment, this.onSwitch});

  @override
  visitCall(js.Call node) {
    if (onCall != null) onCall(node);
    super.visitCall(node);
  }

  @override
  visitAccess(js.PropertyAccess node) {
    if (onPropertyAccess != null) onPropertyAccess(node);
    super.visitAccess(node);
  }

  @override
  visitAssignment(js.Assignment node) {
    if (onAssignment != null) onAssignment(node);
    return super.visitAssignment(node);
  }

  @override
  visitSwitch(js.Switch node) {
    if (onSwitch != null) onSwitch(node);
    return super.visitSwitch(node);
  }
}
