// 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 multiroot 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);
  }
}
