// Copyright (c) 2018, 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';
import 'dart:io' as io;
import 'dart:typed_data';

import 'package:front_end/src/api_unstable/vm.dart';

class HttpAwareFileSystem implements FileSystem {
  FileSystem original;

  HttpAwareFileSystem(this.original);

  @override
  FileSystemEntity entityForUri(Uri uri) {
    if (uri.isScheme('http') || uri.isScheme('https')) {
      return new HttpFileSystemEntity(this, uri);
    } else {
      return original.entityForUri(uri);
    }
  }
}

class HttpFileSystemEntity implements FileSystemEntity {
  HttpAwareFileSystem fileSystem;
  Uri uri;

  HttpFileSystemEntity(this.fileSystem, this.uri);

  @override
  Future<bool> exists() async {
    return connectAndRun((io.HttpClient httpClient) async {
      io.HttpClientRequest request = await httpClient.headUrl(uri);
      io.HttpClientResponse response = await request.close();
      await response.drain();
      return response.statusCode == io.HttpStatus.ok;
    });
  }

  @override
  Future<bool> existsAsyncIfPossible() => exists();

  @override
  Future<Uint8List> readAsBytes() async {
    return connectAndRun((io.HttpClient httpClient) async {
      io.HttpClientRequest request = await httpClient.getUrl(uri);
      io.HttpClientResponse response = await request.close();
      if (response.statusCode != io.HttpStatus.ok) {
        await response.drain();
        throw new FileSystemException(uri, response.toString());
      }
      List<List<int>> list = await response.toList();
      return new Uint8List.fromList(list.expand((list) => list).toList());
    });
  }

  @override
  Future<Uint8List> readAsBytesAsyncIfPossible() => readAsBytes();

  @override
  Future<String> readAsString() async {
    return String.fromCharCodes(await readAsBytes());
  }

  Future<T> connectAndRun<T>(Future<T> body(io.HttpClient httpClient)) async {
    io.HttpClient? httpClient;
    try {
      httpClient = new io.HttpClient();
      // Set timeout to be shorter than anticipated OS default
      httpClient.connectionTimeout = const Duration(seconds: 5);
      return await body(httpClient);
    } on Exception catch (e) {
      throw new FileSystemException(uri, e.toString());
    } finally {
      httpClient?.close(force: true);
    }
  }
}
