// Copyright 2021 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:convert';

import 'package:googleapis/vision/v1.dart' as gcloud;
import 'package:image/image.dart';
import 'package:matcher/matcher.dart';
import 'package:meta/meta.dart';
import 'package:logging/logging.dart';
import 'package:sl4f/sl4f.dart' as sl4f;

import 'gcloud_exceptions.dart';

final _log = Logger('image_matchers');

/// The number of times to retry a Cloud Vision call.
const _visionMaxTries = 2;

/// The amount of time to wait between attempts at talking to the vision server.
/// We should switch to exponential backoff if we want more than 2 attempts.
const _visionTryDelay = Duration(seconds: 2);

/// Error codes that can be retried:
///  DEADLINE_EXCEEDED (4) - Operation took longer than deadline.
///  ABORTED (10) - Operation was aborted due to transaction (or similar).
///  INTERNAL (13) - Server went kaput.
///  UNAVAILABLE (14) - Server went temporarily kaput.
/// We retry on INTERNAL because based on unscientific anecdata it seems that
/// whenever it happens for Cloud Vision the next request is still done
/// successfully.
/// We don't retry on RESOURCE_EXHAUSTED (8) as is unlikely we'll have quota
/// on the next retry.
/// Note that non-idempotent requests may not be retriable despite this.
bool _isRetriableError(int code) =>
    code == 4 || code == 10 || code == 13 || code == 14;

/// Calls Cloud Vision's vision.images.annotate API with retries.
///
/// Throws [VisionException] if there's a non-retriable error or if it fails
/// after retrying.
Future<gcloud.AnnotateImageResponse> invokeAnnotate(gcloud.VisionApi vision,
    {@required String $fields,
    @required gcloud.BatchAnnotateImagesRequest request,
    String dumpName,
    sl4f.Dump dump}) async {
  final output = dump ?? sl4f.Dump();
  final jsonEncoder = JsonUtf8Encoder('  ');
  gcloud.AnnotateImageResponse response;
  for (int attempt = 1; attempt <= _visionMaxTries; attempt++) {
    _log.fine('Calling vision.images.annotate for ${$fields}');
    final batchResponse =
        await vision.images.annotate(request, $fields: $fields);

    if (dumpName != null && dumpName.isNotEmpty) {
      // ignore: unawaited_futures
      output.writeAsBytes('$dumpName-image-annotate', 'json',
          jsonEncoder.convert(batchResponse.toJson()));
    }

    final response = batchResponse.responses.single;
    if (response.error == null) {
      return response;
    }

    if (!_isRetriableError(response.error.code)) {
      throw VisionException(response.error);
    }

    if (attempt < _visionMaxTries) {
      _log.warning('Retrying Cloud Vision request after $_visionTryDelay.');
      await Future.delayed(_visionTryDelay);
    }
  }
  throw VisionException(response.error);
}

/// Annotates an [image] with web entities and OCR.
///
/// Throws [VisionException] if there's a problem communicating with Cloud
/// Vision.
Future<gcloud.AnnotateImageResponse> annotateImage(
    gcloud.VisionApi vision, Image image,
    {sl4f.Dump dump}) async {
  // Field selector constructed using
  // https://developers.google.com/apis-explorer fields editor.
  const $fields = 'responses(error,textAnnotations/'
      'description,webDetection(webEntities(description,score)))';

  final request = gcloud.BatchAnnotateImagesRequest()
    ..requests = [
      gcloud.AnnotateImageRequest()
        ..image = (gcloud.Image()..content = base64Encode(encodePng(image)))
        ..features = [
          gcloud.Feature()
            ..type = 'WEB_DETECTION'
            ..maxResults = 3,
          gcloud.Feature()
            ..type = 'TEXT_DETECTION'
            ..maxResults = 1
        ]
    ];

  return invokeAnnotate(vision, $fields: $fields, request: request, dump: dump);
}

// Log JSON formatted AnnotateImageResponse
void dumpAnnotateImageResponse(gcloud.AnnotateImageResponse response) =>
    _log.info('AnnotateImageResponse: '
        '${JsonEncoder.withIndent('  ').convert(response)}');

/// Matches a [gcloud.AnnotateImageResponse] with annotated text ([String])
/// that matches the given [matcher].
Matcher textAnnotations(Matcher matcher) =>
    TypeMatcher<gcloud.AnnotateImageResponse>().having((response) {
      // Assumptions:
      // * the first text annotation seems to contain all the recognized text
      // * textAnnotations is either null or nonempty
      final text = response.textAnnotations?.first?.description;
      _log.info('Text: $text');
      return text;
    }, 'text', matcher);

/// Matches a [gcloud.AnnotateImageResponse] with a primary web entity
/// description that matches the given [matcher].
Matcher imageWebEntity(Matcher matcher) =>
    TypeMatcher<gcloud.AnnotateImageResponse>().having((response) {
      // Assumptions:
      // * the first entity has the highest confidence
      // * webEntities is either null or nonempty
      final entity = response.webDetection?.webEntities?.first;
      _log.info('Image of: '
          '${entity == null ? 'null' : '${entity.description} '
              '(score: ${entity.score})'}');
      return entity?.description;
    }, 'primary entity', matcher);
