@use "mode";

@function _prefix($separator, $i) {
  @if $i != 1 {
    @return " " + $separator + " ";
  }
  @return "";
}

@function _not($str, $positive) {
  @return if($positive, $str, "(not " + $str + ")");
}

@function _supportPref($option) {
  @return "-moz-bool-pref(\"#{$option}\")";
}
@function _mediaBoolPref($option) {
  @return "(-moz-bool-pref: \"#{$option}\")";
}
@function _mediaPref($option) {
  @return "-moz-pref(\"#{$option}\")";
}

@function _getOptionSupports($optionNames, $positive: true) {
  $result: "";
  @for $i from 1 through length($optionNames) {
    $option: nth($optionNames, $i);
    $separator: if(
      list-separator($optionNames) == "comma", "or", if(
        list-separator($optionNames) == "space", "and", null
      )
    );
    $result: $result + _prefix($separator, $i);

    @if type-of($option) == "list" {
      $result: $result + "(" + _getOptionSupports($option, $positive) + ")";
    }
    @else {
      $result: $result +  _not(_supportPref($option), $positive);
    }
  }
  @return $result;
}
@function _getOptionSupportsWrapper($optionNames, $positive: true) {
  // Test warning for top level `not`
  @if length($optionNames) == 1 {
    $option: nth($optionNames, 1);
    @if not (type-of($option) == "list") {
      $option: _supportPref($option);
      @return if($positive, $option, "not " + $option);
    }
  }
  @return _getOptionSupports($optionNames, $positive);
}

@function _getOptionMediaBool($optionNames, $positive: true) {
  $result: "";
  @for $i from 1 through length($optionNames) {
    $option: nth($optionNames, $i);
    $separator: if(
      list-separator($optionNames) == "comma", ",", if(
        list-separator($optionNames) == "space", "and", null
      )
    );
    $result: $result + _prefix($separator, $i);

    @if type-of($option) == "list" {
      $result: $result + _getOptionMediaBool($option, $positive) ;
    }
    @else {
      $result: $result +  _not(_mediaBoolPref($option), $positive);
    }
  }
  @return $result;
}

@function _getOptionMedia($optionNames, $positive: true) {
  $result: "";
  @for $i from 1 through length($optionNames) {
    $option: nth($optionNames, $i);
    $separator: if(
      list-separator($optionNames) == "comma", "or", if(
        list-separator($optionNames) == "space", "and", null
      )
    );
    $result: $result + _prefix($separator, $i);

    @if type-of($option) == "list" {
      $result: $result + "(" + _getOptionMedia($option, $positive) + ")";
    }
    @else {
      $result: $result +  _not(_mediaPref($option), $positive);
    }
  }
  @return $result;
}
@function _getOptionMediaWrapper($optionNames, $positive: true) {
  // Test warning for top level `not`
  @if length($optionNames) == 1 {
    $option: nth($optionNames, 1);
    @if not (type-of($option) == "list") {
      $option: _mediaPref($option);
      @return if($positive, $option, "not " + $option);
    }
  }
  @return _getOptionMedia($optionNames, $positive);
}

@mixin Option($optionNames...) {
  @if mode.isMediaPref() {
    @#{media} #{_getOptionMediaWrapper($optionNames)} {
      @content;
    }
  }
  @else if mode.isMediaBoolPref() {
    @media #{_getOptionMediaBool($optionNames)} {
      @content;
    }
  }
  @else {
    @supports #{_getOptionSupportsWrapper($optionNames)} {
      @content;
    }
  }
}

@mixin NotOption($optionNames...) {
  @if mode.isMediaPref() {
    @#{media} #{_getOptionMediaWrapper($optionNames, false)} {
      @content;
    }
  }
  @else if mode.isMediaBoolPref() {
    @media #{_getOptionMediaBool($optionNames, false)} {
      @content;
    }
  }
  @else {
    @supports #{_getOptionSupportsWrapper($optionNames, false)} {
      @content;
    }
  }
}