// Copyright 2018 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 'dart:async';
import 'dart:typed_data';

import 'package:fidl_fuchsia_images/fidl.dart';
import 'package:fidl_fuchsia_modular/fidl.dart';
import 'package:fidl/fidl.dart';
import 'package:http/http.dart' as http;
import 'package:lib.app.dart/logging.dart';
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

export 'dart:typed_data' show Uint8List;
export 'package:fidl_fuchsia_modular/fidl.dart';

/// Dart-idiomatic wrapper to create a modular.Proposal.
class ProposalBuilder {
  String _id;

  /// Creates a new ProposalBuilder for a Proposal with the specified ID.
  ProposalBuilder({
    @required String id,
    @required this.headline,
  })  : assert(id != null && id.isNotEmpty),
        assert(headline != null),
        _id = id;

  /// The commands that will be executed if the proposal is accepted.
  List<StoryCommand> commands = [];

  /// The affinities to stories and/or modules the proposal can have.
  List<ProposalAffinity> affinities = [];

  /// Adds a command to the proposal.
  void addStoryCommand(StoryCommand command) => commands.add(command);

  /// Adds an affinity to the proposal.
  void addStoryAffinity(String storyName) {
    final StoryAffinity storyAffinity = StoryAffinity(
      storyName: storyName,
    );
    affinities.add(ProposalAffinity.withStoryAffinity(storyAffinity));
  }

  /// Sets the story name associated with this proposal. The story name is
  /// defined by the creator of the proposal, and can be re-used across
  /// multiple proposals to refer to the same story. If a story with the
  /// given name is not running, one will be created.
  String storyName;

  /// Sets the creator's confidence that the proposal would be selected if it were
  /// the only one presented to the user.
  double confidence = 0.0;

  /// Sets whether the proposal is for a rich suggestion.
  bool wantsRichSuggestion = false;

  /// Sets the headline of the display information associated with the Proposal.
  String headline = '';

  /// Sets the subheadline of the display information associated with the Proposal.
  String subheadline;

  /// Sets the details string of the display information associated with the Proposal.
  String details;

  /// Sets the image URL which can be used when suggesting the proposal to the user.
  String imageUrl;

  /// The type of image to display with the suggestion.
  SuggestionImageType imageType;

  /// The icon URLs which can be used when suggesting the proposal to the user.
  List<String> iconUrls = [];

  /// Adds an image URL to the proposal's icons, which can be used when suggesting the
  /// proposal to the user.
  void addIconUrl(String iconUrl) => iconUrls.add(iconUrl);

  /// Sets the color of the display information associated with the Proposal.
  /// The color is encoded as 0xaarrggbb.
  int color = 0;

  /// Sets the AnnoyanceType of the display information associated with the Proposal.
  /// This is used as a hint by the framework to determine how to display the
  /// proposal to the user.
  AnnoyanceType annoyanceType = AnnoyanceType.none;

  /// Sets the ProposalListener for the Proposal, which is notified when
  /// the proposal is accepted.
  InterfaceHandle<ProposalListener> listener;

  /// Returns a new proposal built from the current configuration of the
  /// ProposalBuilder.
  Future<Proposal> build() async {
    List<SuggestionDisplayImage> icons = iconUrls == null
        ? <SuggestionDisplayImage>[]
        : (await Future.wait(
            iconUrls.map(
              (String url) => createSuggestionDisplayImage(url: url),
            ),
          ))
            .where((SuggestionDisplayImage icon) => icon != null)
            .toList();

    SuggestionDisplayImage image = await createSuggestionDisplayImage(
      url: imageUrl,
      imageType: imageType,
    );
    assert(headline.isNotEmpty || wantsRichSuggestion);

    return Proposal(
        id: _id,
        storyName: storyName,
        onSelected: commands,
        affinity: affinities,
        confidence: confidence,
        wantsRichSuggestion: wantsRichSuggestion,
        display: SuggestionDisplay(
            headline: headline,
            subheadline: subheadline,
            details: details,
            color: color,
            icons: icons.isEmpty ? null : icons,
            image: image,
            annoyance: annoyanceType),
        listener: listener);
  }
}

/// Reads the data out of a SuggestionDisplayImage.
Uint8List readSuggestionDisplayImage(SuggestionDisplayImage image) =>
    readEncodedImage(image.image);

/// Reads the data out of an EncodedImage.
Uint8List readEncodedImage(EncodedImage image) {
  ReadResult result = image.vmo.read(image.size);
  if (result.status == 0) {
    return result.bytesAsUint8List();
  }
  return null;
}

/// Converts a url into a SizedVmo.  Null is returned if a SizedVmo couldn't
/// be created from the given url.
Future<SizedVmo> urlToVmo(String url) async {
  if (url?.isEmpty ?? true) {
    return null;
  }
  if (url.startsWith('http')) {
    http.Response response = await http.get(url);
    if (response.statusCode != 200) {
      return null;
    }
    HandleResult result = System.vmoCreate(response.bodyBytes.lengthInBytes);
    if (result.status == 0 && result.handle != null) {
      SizedVmo vmo = SizedVmo(
        result.handle,
        response.bodyBytes.lengthInBytes,
      );
      if (vmo.write(response.bodyBytes.buffer.asByteData()) != 0) {
        return null;
      }
      return vmo;
    } else {
      return null;
    }
  } else {
    String modifiedUrl =
        url.startsWith('file://') ? url.substring('file://'.length) : url;
    try {
      return SizedVmo.fromFile(modifiedUrl);
      // ignore: avoid_catching_errors
    } on ZxStatusException catch (e) {
      log.severe('Caught exception reading \'$modifiedUrl\' (\'$url\')! $e');
      return null;
    }
  }
}

/// Creates a SuggestionDIsplayImage from an image url.
Future<SuggestionDisplayImage> createSuggestionDisplayImage({
  String url,
  SuggestionImageType imageType = SuggestionImageType.other,
}) async {
  SizedVmo image = await urlToVmo(url);
  if (image == null) {
    return null;
  }
  return SuggestionDisplayImage(
    image: EncodedImage(vmo: image, size: image.size),
    imageType: imageType,
  );
}
