// 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.

part of app;

final _allocationProfileRepository = new AllocationProfileRepository();
final _breakpointRepository = new BreakpointRepository();
final _classRepository = new ClassRepository();
final _classSampleProfileRepository = new ClassSampleProfileRepository();
final _contextRepository = new ContextRepository();
final _evalRepository = new EvalRepository();
final _fieldRepository = new FieldRepository();
final _functionRepository = new FunctionRepository();
final _heapSnapshotRepository = new HeapSnapshotRepository();
final _icdataRepository = new ICDataRepository();
final _inboundReferencesRepository = new InboundReferencesRepository();
final _instanceRepository = new InstanceRepository();
final _isolateSampleProfileRepository = new IsolateSampleProfileRepository();
final _libraryRepository = new LibraryRepository();
final _megamorphicCacheRepository = new MegamorphicCacheRepository();
final _metricRepository = new MetricRepository();
final _nativeMemorySampleProfileRepository =
    new NativeMemorySampleProfileRepository();
final _objectPoolRepository = new ObjectPoolRepository();
final _objectRepository = new ObjectRepository();
final _objectstoreRepository = new ObjectStoreRepository();
final _persistentHandlesRepository = new PersistentHandlesRepository();
final _portsRepository = new PortsRepository();
final _scriptRepository = new ScriptRepository();
final _singleTargetCacheRepository = new SingleTargetCacheRepository();
final _stronglyReachangleInstancesRepository =
    new StronglyReachableInstancesRepository();
final _subtypeTestCacheRepository = new SubtypeTestCacheRepository();
final _topRetainingInstancesRepository = new TopRetainingInstancesRepository();
final _typeArgumentsRepository = new TypeArgumentsRepository();
final _unlinkedCallRepository = new UnlinkedCallRepository();
final _vmrepository = new VMRepository();

class IsolateNotFound implements Exception {
  String isolateId;
  IsolateNotFound(this.isolateId);
  String toString() => "IsolateNotFound: $isolateId";
}

RetainedSizeRepository _retainedSizeRepository = new RetainedSizeRepository();
ReachableSizeRepository _reachableSizeRepository =
    new ReachableSizeRepository();
RetainingPathRepository _retainingPathRepository =
    new RetainingPathRepository();

/// A [Page] controls the user interface of Observatory. At any given time
/// one page will be the current page. Pages are registered at startup.
/// When the user navigates within the application, each page is asked if it
/// can handle the current location, the first page to say yes, wins.
abstract class Page {
  final ObservatoryApplication app;
  final Map<String, String> internalArguments = <String, String>{};
  HtmlElement element;

  Page(this.app);

  /// Called when the page is installed, this callback must initialize
  /// [element].
  void onInstall();

  /// Called when the page is uninstalled, this callback must clear
  /// [element].
  void onUninstall() {
    element = null;
  }

  /// Called when the page should update its state based on [uri].
  void visit(Uri uri, Map internalArguments) {
    this.internalArguments.clear();
    this.internalArguments.addAll(internalArguments);
    Analytics.reportPageView(uri);
    _visit(uri);
  }

  // Overridden by subclasses.
  void _visit(Uri uri);

  /// Called to test whether this page can visit [uri].
  bool canVisit(Uri uri);
}

/// A [MatchingPage] matches a single uri path.
abstract class MatchingPage extends Page {
  final String path;
  MatchingPage(this.path, app) : super(app);

  void _visit(Uri uri) {
    assert(uri != null);
    assert(canVisit(uri));
  }

  Future<Isolate> getIsolate(Uri uri) {
    var isolateId = uri.queryParameters['isolateId'];
    return app.vm.getIsolate(isolateId).then((isolate) {
      if (isolate == null) {
        throw new IsolateNotFound(isolateId);
      }
      return isolate;
    });
  }

  EditorRepository getEditor(Uri uri) {
    final editor = uri.queryParameters['editor'];
    return new EditorRepository(app.vm, editor: editor);
    return null;
  }

  bool canVisit(Uri uri) => uri.path == path;
}

/// A [SimplePage] matches a single uri path and displays a single element.
class SimplePage extends MatchingPage {
  final String elementTagName;
  SimplePage(String path, this.elementTagName, app) : super(path, app);

  void onInstall() {
    if (element == null) {
      element = new Element.tag(elementTagName);
    }
  }
}

/// Error page for unrecognized paths.
class ErrorPage extends Page {
  ErrorPage(app) : super(app);

  void onInstall() {
    if (element == null) {
      // Lazily create page.
      element = new GeneralErrorElement(app.notifications, queue: app.queue);
    }
  }

  void _visit(Uri uri) {
    assert(element != null);
    assert(canVisit(uri));

    (element as GeneralErrorElement).message = "Path '${uri.path}' not found";
  }

  /// Catch all.
  bool canVisit(Uri uri) => true;
}

/// Top-level vm info page.
class VMPage extends MatchingPage {
  VMPage(app) : super('vm', app);

  final DivElement container = new DivElement();

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }

  void _visit(Uri uri) {
    super._visit(uri);
    if (app.vm == null) {
      Logger.root.severe('VMPage has no VM');
      // Reroute to vm-connect.
      app.locationManager.go(Uris.vmConnect());
      return;
    }
    app.vm.reload().then((VM vm) {
      container.children = [
        new VMViewElement(vm, _vmrepository, app.events, app.notifications,
            new IsolateRepository(app.vm), _scriptRepository,
            queue: app.queue)
      ];
    }).catchError((e, stack) {
      Logger.root.severe('VMPage visit error: $e');
      // Reroute to vm-connect.
      app.locationManager.go(Uris.vmConnect());
    });
  }
}

class FlagsPage extends SimplePage {
  FlagsPage(app) : super('flags', 'flag-list', app);

  @override
  onInstall() {
    element = new FlagListElement(
        app.vm, app.events, new FlagsRepository(app.vm), app.notifications,
        queue: app.queue);
  }

  void _visit(Uri uri) {
    super._visit(uri);
  }
}

class NativeMemoryProfilerPage extends SimplePage {
  NativeMemoryProfilerPage(app)
      : super('native-memory-profile', 'native-memory-profile', app);
  @override
  onInstall() {
    if (element == null) {
      element = new NativeMemoryProfileElement(app.vm, app.events,
          app.notifications, _nativeMemorySampleProfileRepository,
          queue: app.queue);
    }
    assert(element != null);
  }

  void _visit(Uri uri) {
    super._visit(uri);
  }
}

class InspectPage extends MatchingPage {
  InspectPage(app) : super('inspect', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      var objectId = uri.queryParameters['objectId'];
      if (objectId == null) {
        isolate.reload().then(_visitObject);
      } else {
        isolate.getObject(objectId).then(_visitObject);
      }
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }

  Future _visitObject(obj) async {
    container.children = [];
    await obj.reload();
    if (obj is Class) {
      container.children = [
        new ClassViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _classRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _fieldRepository,
            _scriptRepository,
            _objectRepository,
            _evalRepository,
            _stronglyReachangleInstancesRepository,
            _topRetainingInstancesRepository,
            _classSampleProfileRepository,
            queue: app.queue)
      ];
    } else if (obj is Code) {
      await obj.loadScript();
      container.children = [
        new CodeViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is Context) {
      container.children = [
        new ContextViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _contextRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is DartError) {
      container.children = [
        new ErrorViewElement(app.notifications, obj, queue: app.queue)
      ];
    } else if (obj is Field) {
      container.children = [
        new FieldViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _fieldRepository,
            _classRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _scriptRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is Instance) {
      container.children = [
        new InstanceViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _objectRepository,
            _classRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _scriptRepository,
            _evalRepository,
            _typeArgumentsRepository,
            _breakpointRepository,
            _functionRepository,
            queue: app.queue)
      ];
    } else if (obj is Isolate) {
      container.children = [
        new IsolateViewElement(
            app.vm,
            obj,
            app.events,
            app.notifications,
            new IsolateRepository(app.vm),
            _scriptRepository,
            _functionRepository,
            _libraryRepository,
            _objectRepository,
            _evalRepository,
            queue: app.queue)
      ];
    } else if (obj is ServiceFunction) {
      container.children = [
        new FunctionViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _functionRepository,
            _classRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _scriptRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is ICData) {
      container.children = [
        new ICDataViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _icdataRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is SingleTargetCache) {
      container.children = [
        new SingleTargetCacheViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _singleTargetCacheRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is SubtypeTestCache) {
      container.children = [
        new SubtypeTestCacheViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _subtypeTestCacheRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is UnlinkedCall) {
      container.children = [
        new UnlinkedCallViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _unlinkedCallRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is Library) {
      container.children = [
        new LibraryViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _libraryRepository,
            _fieldRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _scriptRepository,
            _objectRepository,
            _evalRepository,
            queue: app.queue)
      ];
    } else if (obj is MegamorphicCache) {
      container.children = [
        new MegamorphicCacheViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _megamorphicCacheRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is ObjectPool) {
      container.children = [
        new ObjectPoolViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _objectPoolRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            queue: app.queue)
      ];
    } else if (obj is Script) {
      var pos;
      if (app.locationManager.internalArguments['pos'] != null) {
        try {
          pos = int.parse(app.locationManager.internalArguments['pos']);
        } catch (_) {}
      }
      container.children = [
        new ScriptViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _scriptRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            _objectRepository,
            pos: pos,
            queue: app.queue)
      ];
    } else if (obj is HeapObject) {
      container.children = [
        new ObjectViewElement(
            app.vm,
            obj.isolate,
            obj,
            app.events,
            app.notifications,
            _objectRepository,
            _retainedSizeRepository,
            _reachableSizeRepository,
            _inboundReferencesRepository,
            _retainingPathRepository,
            queue: app.queue)
      ];
    } else if (obj is Sentinel) {
      container.children = [
        new SentinelViewElement(
            app.vm, obj.isolate, obj, app.events, app.notifications,
            queue: app.queue)
      ];
    } else {
      container.children = [
        new JSONViewElement(obj, app.notifications, queue: app.queue)
      ];
    }
  }
}

/// Class tree page.
class ClassTreePage extends SimplePage {
  ClassTreePage(app) : super('class-tree', 'class-tree', app);

  final DivElement container = new DivElement();

  @override
  void onInstall() {
    element = container;
  }

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new ClassTreeElement(
            app.vm, isolate, app.events, app.notifications, _classRepository)
      ];
    });
  }
}

class DebuggerPage extends MatchingPage {
  DebuggerPage(app) : super('debugger', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) async {
      container.children = [
        new DebuggerPageElement(
            isolate, _objectRepository, _scriptRepository, app.events)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }

  @override
  void onUninstall() {
    super.onUninstall();
    container.children = const [];
  }
}

class ObjectStorePage extends MatchingPage {
  ObjectStorePage(app) : super('object-store', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) async {
      container.children = [
        new ObjectStoreViewElement(isolate.vm, isolate, app.events,
            app.notifications, _objectstoreRepository, _objectRepository)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }
}

class CpuProfilerPage extends MatchingPage {
  CpuProfilerPage(app) : super('profiler', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new CpuProfileElement(isolate.vm, isolate, app.events,
            app.notifications, _isolateSampleProfileRepository)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }
}

class TableCpuProfilerPage extends MatchingPage {
  TableCpuProfilerPage(app) : super('profiler-table', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new CpuProfileTableElement(isolate.vm, isolate, app.events,
            app.notifications, _isolateSampleProfileRepository)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    assert(element != null);
  }
}

class AllocationProfilerPage extends MatchingPage {
  AllocationProfilerPage(app) : super('allocation-profiler', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new AllocationProfileElement(isolate.vm, isolate, app.events,
            app.notifications, _allocationProfileRepository,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    app.startGCEventListener();
  }

  @override
  void onUninstall() {
    super.onUninstall();
    app.stopGCEventListener();
    container.children = const [];
  }
}

class MemoryDashboardPage extends MatchingPage {
  MemoryDashboardPage(app) : super('memory-dashboard', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    if (app.vm == null) {
      Logger.root.severe('MemoryDashboard has no VM');
      // Reroute to vm-connect.
      app.locationManager.go(Uris.vmConnect());
      return;
    }
    final editor = getEditor(uri);
    app.vm.reload().then((VM vm) async {
      // Preload all isolates to avoid sorting problems.
      await Future.wait(vm.isolates.map((i) => i.load()));
      container.children = [
        new MemoryDashboardElement(vm, _vmrepository, new IsolateRepository(vm),
            editor, _allocationProfileRepository, app.events, app.notifications,
            queue: app.queue)
      ];
    }).catchError((e, stack) {
      Logger.root.severe('MemoryDashboard visit error: $e');
      // Reroute to vm-connect.
      app.locationManager.go(Uris.vmConnect());
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
    app.startGCEventListener();
  }

  @override
  void onUninstall() {
    super.onUninstall();
    app.stopGCEventListener();
    container.children = const [];
  }
}

class PortsPage extends MatchingPage {
  PortsPage(app) : super('ports', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new PortsElement(isolate.vm, isolate, app.events, app.notifications,
            _portsRepository, _objectRepository,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
  }
}

class PersistentHandlesPage extends MatchingPage {
  PersistentHandlesPage(app) : super('persistent-handles', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new PersistentHandlesPageElement(isolate.vm, isolate, app.events,
            app.notifications, _persistentHandlesRepository, _objectRepository,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
  }
}

class HeapMapPage extends MatchingPage {
  HeapMapPage(app) : super('heap-map', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new HeapMapElement(isolate.vm, isolate, app.events, app.notifications,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
  }
}

class HeapSnapshotPage extends MatchingPage {
  HeapSnapshotPage(app) : super('heap-snapshot', app);

  final DivElement container = new DivElement();

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) {
      container.children = [
        new HeapSnapshotElement(isolate.vm, isolate, app.events,
            app.notifications, _heapSnapshotRepository, _objectRepository,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
  }
}

class LoggingPage extends MatchingPage {
  LoggingPage(app) : super('logging', app);

  final DivElement container = new DivElement();

  @override
  void onInstall() {
    element = container;
    container.children = const [];
    app.startLoggingEventListener();
  }

  @override
  void onUninstall() {
    super.onUninstall();
    container.children = const [];
    app.stopLoggingEventListener();
  }

  void _visit(Uri uri) {
    assert(element != null);
    assert(canVisit(uri));
    getIsolate(uri).then((isolate) {
      container.children = [
        new LoggingPageElement(app.vm, isolate, app.events, app.notifications,
            queue: app.queue)
      ];
    });
  }
}

class ErrorViewPage extends Page {
  ErrorViewPage(app) : super(app);

  void onInstall() {
    element = new ErrorViewElement(
        app.notifications, app.lastErrorOrException as DartError,
        queue: app.queue);
  }

  void _visit(Uri uri) {
    assert(element != null);
    assert(canVisit(uri));
  }

  // TODO(turnidge): How to test this page?
  bool canVisit(Uri uri) => uri.path == 'error';
}

class VMConnectPage extends Page {
  VMConnectPage(app) : super(app);

  void onInstall() {
    if (element == null) {
      element = new VMConnectElement(
          ObservatoryApplication.app.targets,
          ObservatoryApplication.app.loadCrashDump,
          ObservatoryApplication.app.notifications,
          queue: ObservatoryApplication.app.queue);
    }
    assert(element != null);
  }

  void _visit(Uri uri) {
    assert(element != null);
    assert(canVisit(uri));
  }

  bool canVisit(Uri uri) => uri.path == 'vm-connect';
}

class IsolateReconnectPage extends Page {
  IsolateReconnectPage(app) : super(app);

  final DivElement container = new DivElement();

  void onInstall() {
    element = container;
  }

  void _visit(Uri uri) {
    app.vm.reload();
    container.children = [
      new IsolateReconnectElement(
          app.vm,
          app.events,
          app.notifications,
          uri.queryParameters['isolateId'],
          Uri.parse(uri.queryParameters['originalUri']))
    ];
    assert(element != null);
    assert(canVisit(uri));
  }

  bool canVisit(Uri uri) => uri.path == 'isolate-reconnect';
}

class MetricsPage extends MatchingPage {
  MetricsPage(app) : super('metrics', app);

  final DivElement container = new DivElement();

  Isolate lastIsolate;

  void _visit(Uri uri) {
    super._visit(uri);
    getIsolate(uri).then((isolate) async {
      lastIsolate = isolate;
      container.children = const [];
      await _metricRepository.startSampling(isolate);
      container.children = [
        new MetricsPageElement(isolate.vm, isolate, app.events,
            app.notifications, _metricRepository,
            queue: app.queue)
      ];
    });
  }

  void onInstall() {
    if (element == null) {
      element = container;
    }
  }

  @override
  void onUninstall() {
    super.onUninstall();
    _metricRepository.stopSampling(lastIsolate);
    container.children = const [];
  }
}

class TimelinePage extends Page {
  TimelinePage(app) : super(app);

  void onInstall() {
    element = new TimelinePageElement(app.vm, app.events, app.notifications,
        queue: app.queue);
  }

  void _visit(Uri uri) {
    assert(canVisit(uri));
  }

  bool canVisit(Uri uri) => uri.path == 'timeline';
}
