"use strict";
/**
 * Matcher for "ip" condition
 *
 * Ported from https://github.com/optimizely/client-js/tree/2c185f735f0e87800fdcc35727cb413d11b107d7/src/plugins/feature_ip/matchers
 * Migrated to is-in-subnet for CIDR evaluation, and to using String.prototype.startsWith.
 * @module
 */
const { isInSubnet } = require('is-in-subnet');
module.exports = {
    fieldsNeeded: ['ip'],
    /**
     * @param {String|null} visitorIP
     *        A v4 or v6 IP address for the visitor, if one is known.
     * @param {Object} cond
     * @returns {Boolean|undefined}
     *        Whether the given address satisfies the given condition.
     *        Undefined, if the condition specifies an invalid CIDR or regex pattern, or
     *        if the visitorIP was unknown.
     */
    match(visitorIP, cond) {
        if (!visitorIP) {
            return undefined;
        }
        const matchString = cond['value'];
        const type = cond['match'];
        switch (type) {
            case 'prefix':
                if (visitorIP.startsWith(matchString)) {
                    return true;
                }
                break;
            case 'regex': {
                let regex;
                try {
                    regex = new RegExp(matchString);
                }
                catch (error) {
                    return undefined;
                }
                if (regex.test(visitorIP)) {
                    return true;
                }
                break;
            }
            case 'cidr':
                try {
                    return isInSubnet(visitorIP, matchString);
                }
                catch (error) {
                    return undefined;
                }
            case 'exact':
            default:
                // Backwards compatibility: Some 'ip' conditions may lack a 'match' type.
                // Assume those are 'exact' match.
                if (visitorIP === matchString) {
                    return true;
                }
                break;
        }
        return false;
    },
};
