'use strict';

var GetIntrinsic = require('../GetIntrinsic');

var $TypeError = GetIntrinsic('%TypeError%'); var $SyntaxError = GetIntrinsic('%SyntaxError%');

var has = require('has');

var predicates = {

// https://ecma-international.org/ecma-262/6.0/#sec-property-descriptor-specification-type
'Property Descriptor': function isPropertyDescriptor(ES, Desc) {
        if (ES.Type(Desc) !== 'Object') {
                return false;
        }
        var allowed = {
                '[[Configurable]]': true,
                '[[Enumerable]]': true,
                '[[Get]]': true,
                '[[Set]]': true,
                '[[Value]]': true,
                '[[Writable]]': true
        };

        for (var key in Desc) { // eslint-disable-line
                if (has(Desc, key) && !allowed[key]) {
                        return false;
                }
        }

        var isData = has(Desc, '[[Value]]');
        var IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');
        if (isData && IsAccessor) {
                throw new $TypeError('Property Descriptors may not be both accessor and data descriptors');
        }
        return true;
}

};

module.exports = function assertRecord(ES, recordType, argumentName, value) {

var predicate = predicates[recordType];
if (typeof predicate !== 'function') {
        throw new $SyntaxError('unknown record type: ' + recordType);
}
if (!predicate(ES, value)) {
        throw new $TypeError(argumentName + ' must be a ' + recordType);
}

};