// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Hide the original utf8 [Codec] so that we can export our own implementation
// which adds additional error handling.
import 'dart:convert' hide utf8;
import 'dart:convert' as cnv show Utf8Decoder, utf8;

import 'package:meta/meta.dart';

import 'base/common.dart';
export 'dart:convert' hide Utf8Codec, Utf8Decoder, utf8;

/// The original utf8 encoding for testing overrides only.
///
/// Attempting to use the flutter tool utf8 decoder will surface an analyzer
/// warning that overrides cannot change the default value of a named
/// parameter.
@visibleForTesting
const Encoding utf8ForTesting = cnv.utf8;

/// A [Codec] which reports malformed bytes when decoding.
///
/// Occasionally people end up in a situation where we try to decode bytes
/// that aren't UTF-8 and we're not quite sure how this is happening.
/// This tells people to report a bug when they see this.
class Utf8Codec extends Encoding {
  const Utf8Codec({this.reportErrors = true});

  final bool reportErrors;

  @override
  Converter<List<int>, String> get decoder => reportErrors
    ? const Utf8Decoder()
    : const Utf8Decoder(reportErrors: false);

  @override
  Converter<String, List<int>> get encoder => cnv.utf8.encoder;

  @override
  String get name => cnv.utf8.name;
}

const Encoding utf8 = Utf8Codec();

class Utf8Decoder extends Converter<List<int>, String> {
  const Utf8Decoder({this.reportErrors = true});

  static const cnv.Utf8Decoder _systemDecoder =
      cnv.Utf8Decoder(allowMalformed: true);

  final bool reportErrors;

  @override
  String convert(List<int> input, [int start = 0, int? end]) {
    final String result = _systemDecoder.convert(input, start, end);
    // Finding a Unicode replacement character indicates that the input
    // was malformed.
    if (reportErrors && result.contains('\u{FFFD}')) {
      throwToolExit(
        'Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found while decoding string: $result. '
        'The Flutter team would greatly appreciate if you could file a bug explaining '
        'exactly what you were doing when this happened:\n'
        'https://github.com/flutter/flutter/issues/new/choose\n'
        'The source bytes were:\n$input\n\n');
    }
    return result;
  }

  @override
  ByteConversionSink startChunkedConversion(Sink<String> sink) =>
      _systemDecoder.startChunkedConversion(sink);

  @override
  Stream<String> bind(Stream<List<int>> stream) => _systemDecoder.bind(stream);

  @override
  Converter<List<int>, T> fuse<T>(Converter<String, T> other) =>
      _systemDecoder.fuse(other);
}
