import { __require as requireType } from "../../es-errors/type.js";
import { __require as requireIsObject } from "../../es-object-atoms/isObject.js";
import { __require as requireDefineOwnProperty } from "../helpers/DefineOwnProperty.js";
import { __require as requireIsFullyPopulatedPropertyDescriptor } from "../helpers/isFullyPopulatedPropertyDescriptor.js";
import { __require as requirePropertyDescriptor } from "../helpers/records/property-descriptor.js";
import { __require as requireFromPropertyDescriptor } from "./FromPropertyDescriptor.js";
import { __require as requireIsAccessorDescriptor } from "./IsAccessorDescriptor.js";
import { __require as requireIsDataDescriptor } from "./IsDataDescriptor.js";
import { __require as requireIsGenericDescriptor } from "./IsGenericDescriptor.js";
import { __require as requireIsPropertyKey } from "../helpers/isPropertyKey.js";
import { __require as requireSameValue } from "./SameValue.js";
var ValidateAndApplyPropertyDescriptor;
var hasRequiredValidateAndApplyPropertyDescriptor;
function requireValidateAndApplyPropertyDescriptor() {
  if (hasRequiredValidateAndApplyPropertyDescriptor) return ValidateAndApplyPropertyDescriptor;
  hasRequiredValidateAndApplyPropertyDescriptor = 1;
  var $TypeError = requireType();
  var isObject = requireIsObject();
  var DefineOwnProperty = requireDefineOwnProperty();
  var isFullyPopulatedPropertyDescriptor = requireIsFullyPopulatedPropertyDescriptor();
  var isPropertyDescriptor = requirePropertyDescriptor();
  var FromPropertyDescriptor = requireFromPropertyDescriptor();
  var IsAccessorDescriptor = requireIsAccessorDescriptor();
  var IsDataDescriptor = requireIsDataDescriptor();
  var IsGenericDescriptor = requireIsGenericDescriptor();
  var isPropertyKey = requireIsPropertyKey();
  var SameValue = requireSameValue();
  ValidateAndApplyPropertyDescriptor = function ValidateAndApplyPropertyDescriptor2(O, P, extensible, Desc, current) {
    if (typeof O !== "undefined" && !isObject(O)) {
      throw new $TypeError("Assertion failed: O must be undefined or an Object");
    }
    if (!isPropertyKey(P)) {
      throw new $TypeError("Assertion failed: P must be a Property Key");
    }
    if (typeof extensible !== "boolean") {
      throw new $TypeError("Assertion failed: extensible must be a Boolean");
    }
    if (!isPropertyDescriptor(Desc)) {
      throw new $TypeError("Assertion failed: Desc must be a Property Descriptor");
    }
    if (typeof current !== "undefined" && !isPropertyDescriptor(current)) {
      throw new $TypeError("Assertion failed: current must be a Property Descriptor, or undefined");
    }
    if (typeof current === "undefined") {
      if (!extensible) {
        return false;
      }
      if (typeof O === "undefined") {
        return true;
      }
      if (IsAccessorDescriptor(Desc)) {
        return DefineOwnProperty(
          IsDataDescriptor,
          SameValue,
          FromPropertyDescriptor,
          O,
          P,
          Desc
        );
      }
      return DefineOwnProperty(
        IsDataDescriptor,
        SameValue,
        FromPropertyDescriptor,
        O,
        P,
        {
          "[[Configurable]]": !!Desc["[[Configurable]]"],
          "[[Enumerable]]": !!Desc["[[Enumerable]]"],
          "[[Value]]": Desc["[[Value]]"],
          "[[Writable]]": !!Desc["[[Writable]]"]
        }
      );
    }
    if (!isFullyPopulatedPropertyDescriptor(
      {
        IsAccessorDescriptor,
        IsDataDescriptor
      },
      current
    )) {
      throw new $TypeError("`current`, when present, must be a fully populated and valid Property Descriptor");
    }
    if (!current["[[Configurable]]"]) {
      if ("[[Configurable]]" in Desc && Desc["[[Configurable]]"]) {
        return false;
      }
      if ("[[Enumerable]]" in Desc && !SameValue(Desc["[[Enumerable]]"], current["[[Enumerable]]"])) {
        return false;
      }
      if (!IsGenericDescriptor(Desc) && !SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current))) {
        return false;
      }
      if (IsAccessorDescriptor(current)) {
        if ("[[Get]]" in Desc && !SameValue(Desc["[[Get]]"], current["[[Get]]"])) {
          return false;
        }
        if ("[[Set]]" in Desc && !SameValue(Desc["[[Set]]"], current["[[Set]]"])) {
          return false;
        }
      } else if (!current["[[Writable]]"]) {
        if ("[[Writable]]" in Desc && Desc["[[Writable]]"]) {
          return false;
        }
        if ("[[Value]]" in Desc && !SameValue(Desc["[[Value]]"], current["[[Value]]"])) {
          return false;
        }
      }
    }
    if (typeof O !== "undefined") {
      var configurable;
      var enumerable;
      if (IsDataDescriptor(current) && IsAccessorDescriptor(Desc)) {
        configurable = ("[[Configurable]]" in Desc ? Desc : current)["[[Configurable]]"];
        enumerable = ("[[Enumerable]]" in Desc ? Desc : current)["[[Enumerable]]"];
        return DefineOwnProperty(
          IsDataDescriptor,
          SameValue,
          FromPropertyDescriptor,
          O,
          P,
          {
            "[[Configurable]]": !!configurable,
            "[[Enumerable]]": !!enumerable,
            "[[Get]]": ("[[Get]]" in Desc ? Desc : current)["[[Get]]"],
            "[[Set]]": ("[[Set]]" in Desc ? Desc : current)["[[Set]]"]
          }
        );
      } else if (IsAccessorDescriptor(current) && IsDataDescriptor(Desc)) {
        configurable = ("[[Configurable]]" in Desc ? Desc : current)["[[Configurable]]"];
        enumerable = ("[[Enumerable]]" in Desc ? Desc : current)["[[Enumerable]]"];
        return DefineOwnProperty(
          IsDataDescriptor,
          SameValue,
          FromPropertyDescriptor,
          O,
          P,
          {
            "[[Configurable]]": !!configurable,
            "[[Enumerable]]": !!enumerable,
            "[[Value]]": ("[[Value]]" in Desc ? Desc : current)["[[Value]]"],
            "[[Writable]]": !!("[[Writable]]" in Desc ? Desc : current)["[[Writable]]"]
          }
        );
      }
      return DefineOwnProperty(
        IsDataDescriptor,
        SameValue,
        FromPropertyDescriptor,
        O,
        P,
        Desc
      );
    }
    return true;
  };
  return ValidateAndApplyPropertyDescriptor;
}
export {
  requireValidateAndApplyPropertyDescriptor as __require
};
