// 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 _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 _timelineRepository = new TimelineRepository();
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);
    _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).element;
    }
  }

  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((serviceObject) {
      VM vm = serviceObject;
      container.children = <Element>[
        new VMViewElement(
                vm,
                _vmrepository,
                app.events,
                app.notifications,
                new IsolateRepository(app.vm),
                new IsolateGroupRepository(app.vm),
                _scriptRepository,
                queue: app.queue)
            .element
      ];
    }).catchError((e, stack) {
      Logger.root.severe('VMPage visit error: $e');
      Logger.root.severe('Stack: $stack');
      // 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)
        .element;
  }

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

/// 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 = <Element>[
        new ClassTreeElement(app.vm, isolate, app.events, app.notifications,
                _classRepository)
            .element
      ];
    });
  }
}

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 = <Element>[
        new DebuggerPageElement(
                isolate, _objectRepository, _scriptRepository, app.events)
            .element
      ];
    });
  }

  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 = <Element>[
        new ObjectStoreViewElement(isolate.vm, isolate, app.events,
                app.notifications, _objectstoreRepository, _objectRepository)
            .element
      ];
    });
  }

  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 = <Element>[
        new CpuProfileElement(isolate.vm, isolate, app.events,
                app.notifications, _isolateSampleProfileRepository)
            .element
      ];
    });
  }

  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 = <Element>[
        new CpuProfileTableElement(isolate.vm, isolate, app.events,
                app.notifications, _isolateSampleProfileRepository)
            .element
      ];
    });
  }

  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 = <Element>[
        new AllocationProfileElement(isolate.vm, isolate, app.events,
                app.notifications, _allocationProfileRepository,
                queue: app.queue)
            .element
      ];
    });
  }

  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 = <Element>[
        new PortsElement(isolate.vm, isolate, app.events, app.notifications,
                _portsRepository, _objectRepository,
                queue: app.queue)
            .element
      ];
    });
  }

  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 = <Element>[
        new PersistentHandlesPageElement(
                isolate.vm,
                isolate,
                app.events,
                app.notifications,
                _persistentHandlesRepository,
                _objectRepository,
                queue: app.queue)
            .element
      ];
    });
  }

  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 = <Element>[
        new HeapMapElement(isolate.vm, isolate, app.events, app.notifications,
                queue: app.queue)
            .element
      ];
    });
  }

  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 = <Element>[
        new HeapSnapshotElement(isolate.vm, isolate, app.events,
                app.notifications, _heapSnapshotRepository, _objectRepository,
                queue: app.queue)
            .element
      ];
    });
  }

  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 = <Element>[
        new LoggingPageElement(app.vm, isolate, app.events, app.notifications,
                queue: app.queue)
            .element
      ];
    });
  }
}

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

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

  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.notifications,
              queue: ObservatoryApplication.app.queue)
          .element;
    }
    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 = <Element>[
      new IsolateReconnectElement(
              app.vm,
              app.events,
              app.notifications,
              uri.queryParameters['isolateId'],
              Uri.parse(uri.queryParameters['originalUri']))
          .element
    ];
    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 = <Element>[
        new MetricsPageElement(isolate.vm, isolate, app.events,
                app.notifications, _metricRepository,
                queue: app.queue)
            .element
      ];
    });
  }

  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, _timelineRepository, app.events, app.notifications,
            queue: app.queue)
        .element;
  }

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

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

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

  DivElement container = new DivElement();

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

  void _visit(Uri uri) {
    assert(canVisit(uri));
    app.vm.load().then((_) {
      container.children = <Element>[
        new TimelineDashboardElement(
                app.vm, _timelineRepository, app.notifications,
                queue: app.queue)
            .element
      ];
    });
  }

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

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

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

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

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

  bool canVisit(Uri uri) => uri.path == 'process-snapshot';
}
