/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.lettuce.core;

import static io.lettuce.core.protocol.CommandKeyword.*;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.protocol.CommandArgs;

/**
 * Argument list builder for the Redis scan commands ({@literal SCAN, HSCAN, SSCAN, ZSCAN}). Static import the methods from
 *
 * {@link Builder} and chain the method calls: {@code matches("weight_*").limit(2)}.
 * <p>
 * {@link ScanArgs} is a mutable object and instances should be used only once to avoid shared mutable state.
 *
 * @author Mark Paluch
 * @author Ge Jun
 * @since 3.0
 */
public class ScanArgs implements CompositeArgument {

    private Long count;

    private String match;

    private Charset charset;

    /**
     * Builder entry points for {@link ScanArgs}.
     */
    public static class Builder {

        /**
         * Utility constructor.
         */
        private Builder() {
        }

        /**
         * Creates new {@link ScanArgs} with {@literal LIMIT} set.
         *
         * @param count number of elements to scan
         * @return new {@link ScanArgs} with {@literal LIMIT} set.
         * @see ScanArgs#limit(long)
         */
        public static ScanArgs limit(long count) {
            return new ScanArgs().limit(count);
        }

        /**
         * Creates new {@link ScanArgs} with {@literal MATCH} set.
         *
         * @param matches the filter.
         * @return new {@link ScanArgs} with {@literal MATCH} set.
         * @see ScanArgs#match(String)
         */
        public static ScanArgs matches(String matches) {
            return new ScanArgs().match(matches);
        }

    }

    /**
     * Set the match filter. Uses {@link StandardCharsets#UTF_8 UTF-8} to encode {@code match}.
     *
     * @param match the filter, must not be {@code null}.
     * @return {@literal this} {@link ScanArgs}.
     */
    public ScanArgs match(String match) {
        return match(match, StandardCharsets.UTF_8);
    }

    /**
     * Set the match filter along the given {@link Charset}.
     *
     * @param match the filter, must not be {@code null}.
     * @param charset the charset for match, must not be {@code null}.
     * @return {@literal this} {@link ScanArgs}.
     * @since 6.0
     */
    public ScanArgs match(String match, Charset charset) {

        LettuceAssert.notNull(match, "Match must not be null");
        LettuceAssert.notNull(charset, "Charset must not be null");

        this.match = match;
        this.charset = charset;
        return this;
    }

    /**
     * Limit the scan by count
     *
     * @param count number of elements to scan
     * @return {@literal this} {@link ScanArgs}.
     */
    public ScanArgs limit(long count) {

        this.count = count;
        return this;
    }

    @Override
    public <K, V> void build(CommandArgs<K, V> args) {

        if (match != null) {
            args.add(MATCH).add(match.getBytes(charset));
        }

        if (count != null) {
            args.add(COUNT).add(count);
        }
    }

}

@@ -1358,50 +1358,20 @@
 ate 
-String match;%0A%0A    private Charset charset
+byte%5B%5D match
 ;%0A%0A 
@@ -2292,24 +2292,412 @@
 %0A        %7D%0A%0A
+        /**%0A         * Creates new %7B@link ScanArgs%7D with %7B@literal MATCH%7D set.%0A         *%0A         * @param matches the filter.%0A         * @return new %7B@link ScanArgs%7D with %7B@literal MATCH%7D set.%0A         * @since 6.0.4%0A         * @see ScanArgs#match(byte%5B%5D)%0A         */%0A        public static ScanArgs matches(byte%5B%5D matches) %7B%0A            return new ScanArgs().match(matches);%0A        %7D%0A%0A
     %7D%0A%0A    /
@@ -3504,60 +3504,452 @@
     
-this.match = match;%0A        this.charset = charset
+return match(match.getBytes(charset));%0A    %7D%0A%0A    /**%0A     * Set the match filter.%0A     *%0A     * @param match the filter, must not be %7B@code null%7D.%0A     * @return %7B@literal this%7D %7B@link ScanArgs%7D.%0A     * @since 6.0.4%0A     */%0A    public ScanArgs match(byte%5B%5D match) %7B%0A%0A        LettuceAssert.notNull(match, %22Match must not be null%22);%0A%0A        this.match = new byte%5Bmatch.length%5D;%0A        System.arraycopy(match, 0, this.match, 0, match.length)
 ;%0A
+%0A
     
@@ -4310,32 +4310,32 @@
 atch != null) %7B%0A
+
             args
@@ -4355,34 +4355,16 @@
 dd(match
-.getBytes(charset)
 );%0A     

Add overload to ScanArgs to accept a binary match #1675