// Copyright (c) 2016, 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.

import 'dart:async' show Future, Stream;
import 'dart:convert' show Encoding, latin1, utf8;
import 'dart:io'
    show
        File,
        HttpStatus,
        HttpClient,
        HttpClientResponse,
        HttpClientRequest,
        HttpException,
        HttpHeaders;

import 'package:typed_data/typed_buffers.dart' show Uint8Buffer;

/// Read the bytes of a URI as a stream of bytes.
Stream<List<int>> readAsStream(Uri uri) async* {
  if (uri.scheme == 'file') {
    yield* File.fromUri(uri).openRead();
    return;
  }
  if (uri.scheme == 'http' || uri.scheme == 'https') {
    var response = await _httpGetBytes(uri);
    _throwIfFailed(response, uri);
    yield* response;
    return;
  }
  if (uri.scheme == 'data') {
    yield uri.data.contentAsBytes();
    return;
  }
  throw UnsupportedError('Unsupported scheme: $uri');
}

/// Read the bytes of a URI as a list of bytes.
Future<List<int>> readAsBytes(Uri uri) async {
  if (uri.scheme == 'file') {
    return File.fromUri(uri).readAsBytes();
  }
  if (uri.scheme == 'http' || uri.scheme == 'https') {
    var response = await _httpGetBytes(uri);
    _throwIfFailed(response, uri);
    var length = response.contentLength;
    if (length < 0) length = 0;
    // Create empty buffer with capacity matching contentLength.
    var buffer = Uint8Buffer(length)..length = 0;
    await for (var bytes in response) {
      buffer.addAll(bytes);
    }
    return buffer.toList();
  }
  if (uri.scheme == 'data') {
    return uri.data.contentAsBytes();
  }
  throw UnsupportedError('Unsupported scheme: $uri');
}

/// Read the bytes of a URI as a string.
Future<String> readAsString(Uri uri, Encoding encoding) async {
  if (uri.scheme == 'file') {
    encoding ??= utf8;
    return File.fromUri(uri).readAsString(encoding: encoding);
  }
  if (uri.scheme == 'http' || uri.scheme == 'https') {
    var request = await HttpClient().getUrl(uri);
    // Prefer text/plain, text/* if possible, otherwise take whatever is there.
    request.headers.set(HttpHeaders.acceptHeader, 'text/plain, text/*, */*');
    if (encoding != null) {
      request.headers.set(HttpHeaders.acceptCharsetHeader, encoding.name);
    }
    var response = await request.close();
    _throwIfFailed(response, uri);
    encoding ??= Encoding.getByName(response.headers.contentType?.charset);
    if (encoding == null || encoding == latin1) {
      // Default to LATIN-1 if no encoding found.
      // Special case LATIN-1 since it is common and doesn't need decoding.
      var length = response.contentLength;
      if (length < 0) length = 0;
      // Create empty buffer with capacity matching contentLength.
      var buffer = Uint8Buffer(length)..length = 0;
      await for (var bytes in response) {
        buffer.addAll(bytes);
      }
      var byteList = buffer.buffer.asUint8List(0, buffer.length);
      return String.fromCharCodes(byteList);
    }
    return response.cast<List<int>>().transform(encoding.decoder).join();
  }
  if (uri.scheme == 'data') {
    return uri.data.contentAsString(encoding: encoding);
  }
  throw UnsupportedError('Unsupported scheme: $uri');
}

HttpClient _sharedHttpClient = HttpClient()..maxConnectionsPerHost = 6;

Future<HttpClientResponse> _httpGetBytes(Uri uri) async {
  // ignore: omit_local_variable_types
  HttpClientRequest request = await _sharedHttpClient.getUrl(uri);
  request.headers
      .set(HttpHeaders.acceptHeader, 'application/octet-stream, */*');
  return request.close();
}

void _throwIfFailed(HttpClientResponse response, Uri uri) {
  var statusCode = response.statusCode;
  if (statusCode < HttpStatus.ok || statusCode > HttpStatus.noContent) {
    throw HttpException(response.reasonPhrase, uri: uri);
  }
}
