// Copyright (c) 2015, 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:collection';

import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/source.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart'
    show DartUriResolver, SourceFactory, UriResolver;
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/utilities/uri_cache.dart';
import 'package:analyzer/src/workspace/pub.dart';

/// Return `true` if the given [source] refers to a file that is assumed to be
/// generated.
bool isGeneratedSource(Source? source) {
  if (source == null) {
    return false;
  }
  return file_paths.isGenerated(source.fullName);
}

/// Instances of the class `SourceFactory` resolve possibly relative URI's
/// against an existing [Source].
class SourceFactoryImpl implements SourceFactory {
  /// The resolvers used to resolve absolute URI's.
  final List<UriResolver> resolvers;

  /// Cache of mapping of absolute [Uri]s to [Source]s.
  final HashMap<Uri, Source> _absoluteUriToSourceCache = HashMap<Uri, Source>();

  /// Initialize a newly created source factory with the given absolute URI
  /// [resolvers].
  SourceFactoryImpl(this.resolvers);

  @override
  DartSdk? get dartSdk {
    int length = resolvers.length;
    for (int i = 0; i < length; i++) {
      var resolver = resolvers[i];
      if (resolver is DartUriResolver) {
        return resolver.dartSdk;
      }
    }
    return null;
  }

  @override
  Map<String, List<Folder>>? get packageMap {
    for (var resolver in resolvers) {
      if (resolver is PackageMapUriResolver) {
        return resolver.packageMap;
      }
      if (resolver is PackageConfigPackageUriResolver) {
        return resolver.packageMap;
      }
    }
    return null;
  }

  @override
  Source? forUri(String absoluteUri) {
    try {
      Uri uri;
      try {
        uri = uriCache.parse(absoluteUri);
      } catch (exception, stackTrace) {
        AnalysisEngine.instance.instrumentationService.logInfo(
          'Could not resolve URI: $absoluteUri $stackTrace',
        );
        return null;
      }
      if (uri.isAbsolute) {
        return _internalResolveUri(null, uri);
      }
    } catch (exception, stackTrace) {
      // TODO(39284): should this exception be silent?
      AnalysisEngine.instance.instrumentationService.logException(
        SilentException(
          "Could not resolve URI: $absoluteUri",
          exception,
          stackTrace,
        ),
      );
    }
    return null;
  }

  @override
  Source? forUri2(Uri absoluteUri) {
    if (absoluteUri.isAbsolute) {
      try {
        return _internalResolveUri(null, absoluteUri);
      } on AnalysisException catch (exception, stackTrace) {
        // TODO(39284): should this exception be silent?
        AnalysisEngine.instance.instrumentationService.logException(
          SilentException(
            "Could not resolve URI: $absoluteUri",
            exception,
            stackTrace,
          ),
        );
      }
    }
    return null;
  }

  @override
  Uri? pathToUri(String path) {
    for (var resolver in resolvers) {
      var uri = resolver.pathToUri(path);
      if (uri != null) {
        return uri;
      }
    }
    return null;
  }

  @override
  Source? resolveUri(Source? containingSource, String? containedUri) {
    if (containedUri == null) {
      return null;
    }
    if (containedUri.isEmpty) {
      return containingSource;
    }
    try {
      // Force the creation of an escaped URI to deal with spaces, etc.
      return _internalResolveUri(
        containingSource,
        uriCache.parse(containedUri),
      );
    } on FormatException {
      return null;
    } catch (exception, stackTrace) {
      String containingFullName =
          containingSource != null ? containingSource.fullName : '<null>';
      // TODO(39284): should this exception be silent?
      AnalysisEngine.instance.instrumentationService.logException(
        SilentException(
          "Could not resolve URI ($containedUri) "
          "relative to source ($containingFullName)",
          exception,
          stackTrace,
        ),
      );
      return null;
    }
  }

  /// Return a source object representing the URI that results from resolving
  /// the given (possibly relative) contained URI against the URI associated
  /// with an existing source object, or `null` if the URI could not be
  /// resolved.
  ///
  /// @param containingSource the source containing the given URI
  /// @param containedUri the (possibly relative) URI to be resolved against the
  ///        containing source
  /// @return the source representing the contained URI
  /// @throws AnalysisException if either the contained URI is invalid or if it
  ///         cannot be resolved against the source object's URI
  Source? _internalResolveUri(Source? containingSource, Uri containedUri) {
    if (!containedUri.isAbsolute) {
      if (containingSource == null) {
        throw AnalysisException(
          "Cannot resolve a relative URI without a containing source: "
          "$containedUri",
        );
      }
      containedUri = uriCache.resolveRelative(
        containingSource.uri,
        containedUri,
      );
    }

    var result = _absoluteUriToSourceCache[containedUri];
    if (result == null) {
      for (UriResolver resolver in resolvers) {
        result = resolver.resolveAbsolute(containedUri);
        if (result != null) {
          _absoluteUriToSourceCache[containedUri] = result;
          break;
        }
      }
    }
    return result;
  }
}
