// Copyright 2019 The Fuchsia Authors. 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:fidl_fuchsia_sys_index/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:flutter/foundation.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_services/services.dart';
import 'package:meta/meta.dart';

import 'suggestion.dart';

const _kComponentIndexUrl =
    'fuchsia-pkg://fuchsia.com/component_index#meta/component_index.cmx';

/// Class to encapsulate the functionality of the Suggestions Engine.
class SuggestionService {
  final ComponentIndexProxy _componentIndex;
  final LauncherProxy _launcher;
  final ValueChanged<Suggestion> _onSuggestion;

  /// Constructor.
  const SuggestionService({
    @required ComponentIndex componentIndex,
    @required Launcher launcher,
    ValueChanged<Suggestion> onSuggestion,
  })  : _componentIndex = componentIndex,
        _launcher = launcher,
        _onSuggestion = onSuggestion;

  /// Construct from [StartupContext].
  factory SuggestionService.fromStartupContext({
    StartupContext startupContext,
    ValueChanged<Suggestion> onSuggestion,
  }) {
    final launcher = LauncherProxy();
    startupContext.incoming.connectToService(launcher);

    final Incoming incoming = Incoming();
    final ComponentControllerProxy componentIndexController =
        ComponentControllerProxy();
    launcher.createComponent(
      LaunchInfo(
        url: _kComponentIndexUrl,
        directoryRequest: incoming.request().passChannel(),
      ),
      componentIndexController.ctrl.request(),
    );

    final componentIndex = ComponentIndexProxy();
    incoming
      ..connectToService(componentIndex)
      ..close();

    return SuggestionService(
      componentIndex: componentIndex,
      launcher: launcher,
      onSuggestion: onSuggestion,
    );
  }

  /// Release FIDL services.
  void dispose() {
    _componentIndex.ctrl.close();
    _launcher.ctrl.close();
  }

  /// Returns an [Iterable<Suggestion>] for given [query].
  Future<Iterable<Suggestion>> getSuggestions(String query,
      [int maxSuggestions = 20]) async {
    final newSuggestions = <Suggestion>[];
    // Allow only non empty queries.
    if (query.isEmpty) {
      return newSuggestions;
    }

    try {
      final results = await _componentIndex.fuzzySearch(query);
      newSuggestions.addAll(results.map((url) {
        final re = RegExp(r'fuchsia-pkg://fuchsia.com/(.+)#meta/.+');
        final name = re.firstMatch(url)?.group(1);
        return Suggestion(
          id: '$url:${DateTime.now().millisecondsSinceEpoch}',
          url: url,
          title: name,
        );
      }));
    } on Exception catch (e) {
      log.info('Component Index error: $e');
    }

    return newSuggestions.take(maxSuggestions);
  }

  /// Invokes the [suggestion].
  Future<void> invokeSuggestion(Suggestion suggestion) async {
    _onSuggestion?.call(suggestion);
  }
}
