001/*
002 *     Copyright 2021 Siroshun09
003 *
004 *     Licensed under the Apache License, Version 2.0 (the "License");
005 *     you may not use this file except in compliance with the License.
006 *     You may obtain a copy of the License at
007 *
008 *         http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *     Unless required by applicable law or agreed to in writing, software
011 *     distributed under the License is distributed on an "AS IS" BASIS,
012 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *     See the License for the specific language governing permissions and
014 *     limitations under the License.
015 */
016
017package com.github.siroshun09.mccommand.common.context;
018
019import com.github.siroshun09.mccommand.common.Command;
020import com.github.siroshun09.mccommand.common.argument.Argument;
021import com.github.siroshun09.mccommand.common.sender.Sender;
022import org.jetbrains.annotations.NotNull;
023
024import java.util.ArrayList;
025import java.util.List;
026import java.util.Objects;
027
028/**
029 * The {@link CommandContext} implementation class.
030 */
031public class SimpleCommandContext implements CommandContext {
032
033    private final Command command;
034    private final Sender sender;
035    private final List<Argument> arguments;
036    private final String label;
037
038    /**
039     * Creates a {@link SimpleCommandContext}
040     *
041     * @param command   the executed command
042     * @param sender    the commander
043     * @param arguments the given arguments
044     * @param label     the string used to specify the command
045     */
046    public SimpleCommandContext(@NotNull Command command, @NotNull Sender sender,
047                                @NotNull List<Argument> arguments, @NotNull String label) {
048        this.command = command;
049        this.sender = sender;
050        this.arguments = List.copyOf(arguments);
051        this.label = label;
052    }
053
054    /**
055     * Gets the new {@link SimpleCommandContextBuilder}
056     *
057     * @return the new {@link SimpleCommandContextBuilder}
058     */
059    @NotNull
060    public static SimpleCommandContextBuilder newBuilder() {
061        return new SimpleCommandContextBuilder();
062    }
063
064    /**
065     * {@inheritDoc}
066     */
067    @NotNull
068    @Override
069    public Command getCommand() {
070        return command;
071    }
072
073    /**
074     * {@inheritDoc}
075     */
076    @NotNull
077    @Override
078    public Sender getSender() {
079        return sender;
080    }
081
082    /**
083     * {@inheritDoc}
084     */
085    @NotNull
086    @Override
087    public List<Argument> getArguments() {
088        return arguments;
089    }
090
091    /**
092     * {@inheritDoc}
093     */
094    @NotNull
095    @Override
096    public String getLabel() {
097        return label;
098    }
099
100    @Override
101    public boolean equals(Object o) {
102        if (this == o) {
103            return true;
104        }
105
106        if (!(o instanceof CommandContext)) {
107            return false;
108        }
109
110        CommandContext that = (CommandContext) o;
111
112        return getCommand().equals(that.getCommand()) &&
113                getSender().equals(that.getSender()) &&
114                getArguments().equals(that.getArguments()) &&
115                getLabel().equals(that.getLabel());
116    }
117
118    @Override
119    public int hashCode() {
120        return Objects.hash(getCommand(), getSender(), getArguments(), getLabel());
121    }
122
123    @Override
124    public String toString() {
125        return "SimpleCommandContext{" +
126                "command=" + command +
127                ", sender=" + sender +
128                ", arguments=" + arguments +
129                ", label='" + label + '\'' +
130                '}';
131    }
132
133    /**
134     * Builder class of {@link CommandContext}.
135     */
136    public static class SimpleCommandContextBuilder {
137        private Command command;
138        private Sender sender;
139        private List<Argument> arguments;
140        private String label;
141
142        private SimpleCommandContextBuilder() {
143        }
144
145        /**
146         * Sets the executed command.
147         *
148         * @param command the executed command
149         * @return the builder instance
150         */
151        public SimpleCommandContextBuilder setCommand(Command command) {
152            this.command = command;
153            return this;
154        }
155
156        /**
157         * Sets the commander.
158         *
159         * @param sender the commander
160         * @return the builder instance
161         */
162        public SimpleCommandContextBuilder setSender(Sender sender) {
163            this.sender = sender;
164            return this;
165        }
166
167        /**
168         * Sets the arguments.
169         *
170         * @param arguments the given arguments
171         * @return the builder instance
172         */
173        public SimpleCommandContextBuilder setArguments(List<Argument> arguments) {
174            this.arguments = arguments;
175            return this;
176        }
177
178        /**
179         * Sets the arguments.
180         *
181         * @param arguments the given arguments
182         * @return the builder instance
183         * @throws NullPointerException if arguments is null
184         */
185        public SimpleCommandContextBuilder setArguments(@NotNull String[] arguments) {
186            Objects.requireNonNull(arguments);
187            List<Argument> result = new ArrayList<>();
188
189            for (int i = 0; i < arguments.length; i++) {
190                String arg = Objects.requireNonNull(arguments[i]);
191                result.add(Argument.of(i, arg));
192            }
193
194            return setArguments(result);
195        }
196
197        /**
198         * Sets the string used to specify the command.
199         *
200         * @param label the string used to specify the command
201         * @return the builder instance
202         */
203        public SimpleCommandContextBuilder setLabel(String label) {
204            this.label = label;
205
206            return this;
207        }
208
209        /**
210         * Builds the {@link CommandContext}
211         *
212         * @return the {@link CommandContext}
213         * @throws NullPointerException if any of the values are not set
214         */
215        @NotNull
216        public CommandContext build() {
217            Objects.requireNonNull(command);
218            Objects.requireNonNull(sender);
219            Objects.requireNonNull(arguments);
220            Objects.requireNonNull(label);
221
222            return new SimpleCommandContext(command, sender, arguments, label);
223        }
224    }
225}