// Copyright (c) 2017, 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 'package:built_value/built_value.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';

import '../base.dart';
import '../visitors.dart';

part 'directive.g.dart';

@immutable
abstract class Directive
    implements Built<Directive, DirectiveBuilder>, Spec, Comparable<Directive> {
  factory Directive([void Function(DirectiveBuilder) updates]) = _$Directive;

  factory Directive.import(
    String url, {
    String? as,
    List<String> show = const [],
    List<String> hide = const [],
  }) => Directive(
    (builder) =>
        builder
          ..as = as
          ..type = DirectiveType.import
          ..url = url
          ..show.addAll(show)
          ..hide.addAll(hide),
  );

  factory Directive.importDeferredAs(
    String url,
    String as, {
    List<String> show = const [],
    List<String> hide = const [],
  }) => Directive(
    (builder) =>
        builder
          ..as = as
          ..type = DirectiveType.import
          ..url = url
          ..deferred = true
          ..show.addAll(show)
          ..hide.addAll(hide),
  );

  factory Directive.export(
    String url, {
    List<String> show = const [],
    List<String> hide = const [],
  }) => Directive(
    (builder) =>
        builder
          ..type = DirectiveType.export
          ..url = url
          ..show.addAll(show)
          ..hide.addAll(hide),
  );

  factory Directive.part(String url) => Directive(
    (builder) =>
        builder
          ..type = DirectiveType.part
          ..url = url,
  );

  factory Directive.partOf(String url) => Directive(
    (builder) =>
        builder
          ..type = DirectiveType.partOf
          ..url = url,
  );

  Directive._();

  String? get as;

  String get url;

  DirectiveType get type;

  List<String> get show;

  List<String> get hide;

  bool get deferred;

  @override
  R accept<R>(SpecVisitor<R> visitor, [R? context]) =>
      visitor.visitDirective(this, context);

  @override
  int compareTo(Directive other) => _compareDirectives(this, other);
}

abstract class DirectiveBuilder
    implements Builder<Directive, DirectiveBuilder> {
  factory DirectiveBuilder() = _$DirectiveBuilder;

  DirectiveBuilder._();

  bool deferred = false;

  String? as;

  String? url;

  List<String> show = <String>[];

  List<String> hide = <String>[];

  DirectiveType? type;
}

enum DirectiveType { import, export, part, partOf }

/// Sort import URIs represented by [a] and [b] to honor the
/// "Effective Dart" ordering rules which are enforced by the
/// `directives_ordering` lint.
///
/// 1. `import`s before `export`s
/// 2. `dart:`
/// 3. `package:`
/// 4. relative
/// 5. `part`s
int _compareDirectives(Directive a, Directive b) {
  // NOTE: using the fact that `import` is before `export` in the
  // `DirectiveType` enum – which allows us to compare using `indexOf`.
  var value = DirectiveType.values
      .indexOf(a.type)
      .compareTo(DirectiveType.values.indexOf(b.type));

  if (value == 0) {
    final uriA = Uri.parse(a.url);
    final uriB = Uri.parse(b.url);

    if (uriA.hasScheme) {
      if (uriB.hasScheme) {
        // If both import URIs have schemes, compare them based on scheme
        // `dart` will sort before `package` which is what we want
        // schemes are case-insensitive, so compare accordingly
        value = compareAsciiLowerCase(uriA.scheme, uriB.scheme);
      } else {
        value = -1;
      }
    } else if (uriB.hasScheme) {
      value = 1;
    }

    // If both schemes are the same, compare based on path
    if (value == 0) {
      value = compareAsciiLowerCase(uriA.path, uriB.path);
    }

    assert((value == 0) == (a.url == b.url));
  }

  return value;
}
