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

import 'package:build/build.dart';
import 'package:build_runner_core/build_runner_core.dart';
import 'package:build_runner_core/src/generate/phase.dart';
import 'package:crypto/crypto.dart';
import 'package:glob/glob.dart';

import '../asset_graph/graph.dart';
import '../asset_graph/node.dart';
import '../asset_graph/optional_output_tracker.dart';

/// An [AssetReader] which ignores deleted files.
class FinalizedReader implements AssetReader {
  final AssetReader _delegate;
  final AssetGraph _assetGraph;
  OptionalOutputTracker _optionalOutputTracker;
  final String _rootPackage;
  final List<BuildPhase> _buildPhases;

  void reset(Set<String> buildDirs, Set<BuildFilter> buildFilters) {
    _optionalOutputTracker = OptionalOutputTracker(
        _assetGraph, buildDirs, buildFilters, _buildPhases);
  }

  FinalizedReader(
      this._delegate, this._assetGraph, this._buildPhases, this._rootPackage);

  /// Returns a reason why [id] is not readable, or null if it is readable.
  Future<UnreadableReason> unreadableReason(AssetId id) async {
    if (!_assetGraph.contains(id)) return UnreadableReason.notFound;
    var node = _assetGraph.get(id);
    if (node.isDeleted) return UnreadableReason.deleted;
    if (!node.isReadable) return UnreadableReason.assetType;
    if (node is GeneratedAssetNode) {
      if (node.isFailure) return UnreadableReason.failed;
      if (!(node.wasOutput && (_optionalOutputTracker.isRequired(node.id)))) {
        return UnreadableReason.notOutput;
      }
    }
    if (await _delegate.canRead(id)) return null;
    return UnreadableReason.unknown;
  }

  @override
  Future<bool> canRead(AssetId id) async =>
      (await unreadableReason(id)) == null;

  @override
  Future<Digest> digest(AssetId id) => _delegate.digest(id);

  @override
  Future<List<int>> readAsBytes(AssetId id) => _delegate.readAsBytes(id);

  @override
  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async {
    if (_assetGraph.get(id)?.isDeleted ?? true) {
      throw AssetNotFoundException(id);
    }
    return _delegate.readAsString(id, encoding: encoding);
  }

  @override
  Stream<AssetId> findAssets(Glob glob) async* {
    var potentialNodes = _assetGraph
        .packageNodes(_rootPackage)
        .where((n) => glob.matches(n.id.path))
        .toList();
    var potentialIds = potentialNodes.map((n) => n.id).toList();

    for (var id in potentialIds) {
      if (await _delegate.canRead(id)) {
        yield id;
      }
    }
  }
}

enum UnreadableReason {
  notFound,
  notOutput,
  assetType,
  deleted,
  failed,
  unknown,
}
