import { AbstractOp } from './AbstractOp';
import { find, formatJsonPointer } from '@jsonjoy.com/json-pointer';
import { OPCODE } from '../constants';
/**
 * @category JSON Patch Extended
 */
export class OpStrDel extends AbstractOp {
    pos;
    str;
    len;
    constructor(path, pos, str, len) {
        super(path);
        this.pos = pos;
        this.str = str;
        this.len = len;
    }
    op() {
        return 'str_del';
    }
    code() {
        return OPCODE.str_del;
    }
    deleteLength() {
        return typeof this.str === 'string' ? this.str.length : this.len;
    }
    apply(doc) {
        const { val, key, obj } = find(doc, this.path);
        if (typeof val !== 'string')
            throw new Error('NOT_A_STRING');
        const length = val.length;
        const pos = Math.min(this.pos, val.length);
        const start = Math.min(pos, length);
        const deletionLength = this.str !== undefined ? this.str.length : this.len;
        const end = Math.min(pos + deletionLength, length);
        const before = val.slice(0, start);
        const after = val.substr(end);
        const result = before + after;
        if (obj)
            obj[key] = result;
        else
            doc = result;
        return { doc, old: val };
    }
    toJson(parent) {
        if (typeof this.str === 'string') {
            return {
                op: 'str_del',
                path: formatJsonPointer(this.path),
                pos: this.pos,
                str: this.str,
            };
        }
        return {
            op: 'str_del',
            path: formatJsonPointer(this.path),
            pos: this.pos,
            len: this.len,
        };
    }
    toCompact(parent, verbose) {
        const opcode = verbose ? 'str_del' : OPCODE.str_del;
        return typeof this.str === 'string'
            ? [opcode, this.path, this.pos, this.str]
            : [opcode, this.path, this.pos, 0, this.len];
    }
}
//# sourceMappingURL=OpStrDel.js.map