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

// ignore_for_file: implementation_imports
import 'dart:async';
import 'dart:io' as io; // ignore: dart_io_import

import 'package:build/build.dart';
import 'package:build_daemon/client.dart';
import 'package:build_daemon/data/build_status.dart';
import 'package:build_runner_core/build_runner_core.dart' as core;
import 'package:glob/glob.dart';
import 'package:path/path.dart' as path;

import '../base/file_system.dart';
import '../build_info.dart';
import '../convert.dart';
import '../platform_plugins.dart';
import '../plugins.dart';
import '../project.dart';
import '../web/compile.dart';
import 'web_fs.dart';

/// A build_runner specific implementation of the [WebCompilationProxy].
class BuildRunnerWebCompilationProxy extends WebCompilationProxy {
  BuildRunnerWebCompilationProxy();

  @override
  Future<bool> initialize({
    Directory projectDirectory,
    String testOutputDir,
    List<String> testFiles,
    BuildMode mode,
    String projectName,
    bool initializePlatform,
  }) async {
    // Create the .dart_tool directory if it doesn't exist.
    projectDirectory
      .childDirectory('.dart_tool')
      .createSync();
    final FlutterProject flutterProject = FlutterProject.fromDirectory(projectDirectory);
    final bool hasWebPlugins = findPlugins(flutterProject)
        .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
    final BuildDaemonClient client = await buildDaemonCreator.startBuildDaemon(
      projectDirectory.path,
      release: mode == BuildMode.release,
      profile: mode == BuildMode.profile,
      hasPlugins: hasWebPlugins,
      initializePlatform: initializePlatform,
      testTargets: WebTestTargetManifest(
        testFiles
          .map<String>((String absolutePath) {
            final String relativePath = path.relative(absolutePath, from: projectDirectory.path);
            return '${path.withoutExtension(relativePath)}.*';
          })
          .toList(),
      ),
    );
    client.startBuild();
    bool success = true;
    await for (BuildResults results in client.buildResults) {
      final BuildResult result = results.results.firstWhere((BuildResult result) {
        return result.target == 'web';
      });
      if (result.status == BuildStatus.failed) {
        success = false;
        break;
      }
      if (result.status == BuildStatus.succeeded) {
        break;
      }
    }
    if (success && testOutputDir != null) {
      final Directory rootDirectory = projectDirectory
        .childDirectory('.dart_tool')
        .childDirectory('build')
        .childDirectory('flutter_web');

      final Iterable<Directory> childDirectories = rootDirectory
        .listSync()
        .whereType<Directory>();
      for (Directory childDirectory in childDirectories) {
        final String path = fs.path.join(testOutputDir, 'packages',
            fs.path.basename(childDirectory.path));
        copyDirectorySync(childDirectory.childDirectory('lib'), fs.directory(path));
      }
      final Directory outputDirectory = rootDirectory
          .childDirectory(projectName)
          .childDirectory('test');
      copyDirectorySync(outputDirectory, fs.directory(fs.path.join(testOutputDir)));
    }
    return success;
  }
}

/// Handles mapping a single root file scheme to a multi-root scheme.
///
/// This allows one build_runner build to read the output from a previous
/// isolated build.
class MultirootFileBasedAssetReader extends core.FileBasedAssetReader {
  MultirootFileBasedAssetReader(
    core.PackageGraph packageGraph,
    this.generatedDirectory,
  ) : super(packageGraph);

  final Directory generatedDirectory;

  @override
  Future<bool> canRead(AssetId id) {
    if (packageGraph[id.package] == packageGraph.root && _missingSource(id)) {
      return _generatedFile(id).exists();
    }
    return super.canRead(id);
  }

  @override
  Future<List<int>> readAsBytes(AssetId id) {
    if (packageGraph[id.package] == packageGraph.root && _missingSource(id)) {
      return _generatedFile(id).readAsBytes();
    }
    return super.readAsBytes(id);
  }

  @override
  Future<String> readAsString(AssetId id, {Encoding encoding}) {
    if (packageGraph[id.package] == packageGraph.root && _missingSource(id)) {
      return _generatedFile(id).readAsString();
    }
    return super.readAsString(id, encoding: encoding);
  }

  @override
  Stream<AssetId> findAssets(Glob glob, {String package}) async* {
    if (package == null || packageGraph.root.name == package) {
      final String generatedRoot = fs.path.join(generatedDirectory.path, packageGraph.root.name);
      await for (io.FileSystemEntity entity in glob.list(followLinks: true, root: packageGraph.root.path)) {
        if (entity is io.File && _isNotHidden(entity) && !fs.path.isWithin(generatedRoot, entity.path)) {
          yield _fileToAssetId(entity, packageGraph.root);
        }
      }
      if (!fs.isDirectorySync(generatedRoot)) {
        return;
      }
      await for (io.FileSystemEntity entity in glob.list(followLinks: true, root: generatedRoot)) {
        if (entity is io.File && _isNotHidden(entity)) {
          yield _fileToAssetId(entity, packageGraph.root, fs.path.relative(generatedRoot), true);
        }
      }
      return;
    }
    yield* super.findAssets(glob, package: package);
  }

  bool _isNotHidden(io.FileSystemEntity entity) {
    return !path.basename(entity.path).startsWith('._');
  }

  bool _missingSource(AssetId id) {
    return !fs.file(path.joinAll(<String>[packageGraph.root.path, ...id.pathSegments])).existsSync();
  }

  File _generatedFile(AssetId id) {
    return fs.file(
      path.joinAll(<String>[generatedDirectory.path, packageGraph.root.name, ...id.pathSegments])
    );
  }

  /// Creates an [AssetId] for [file], which is a part of [packageNode].
  AssetId _fileToAssetId(io.File file, core.PackageNode packageNode, [String root, bool generated = false]) {
    final String filePath = path.normalize(file.absolute.path);
    String relativePath;
    if (generated) {
      relativePath = filePath.substring(root.length + 2);
    } else {
      relativePath = path.relative(filePath, from: packageNode.path);
    }
    return AssetId(packageNode.name, relativePath);
  }
}
