001package com.streamconverter;
002
003import java.time.Duration;
004import java.time.Instant;
005
006/**
007 * コマンドの実行結果を表すクラス
008 *
009 * <p>各StreamCommandの実行結果、実行時間、エラー情報などを保持します。
010 */
011public final class CommandResult {
012  private final String commandName;
013  private final boolean success;
014  private final long execMillis;
015  private final long inputBytes;
016  private final long outputBytes;
017  private final String errorMessage;
018  private final Instant startTime;
019  private final Instant endTime;
020
021  private CommandResult(final Builder builder) {
022    this.commandName = builder.commandName;
023    this.success = builder.success;
024    this.execMillis = builder.execMillis;
025    this.inputBytes = builder.inputBytes;
026    this.outputBytes = builder.outputBytes;
027    this.errorMessage = builder.errorMessage;
028    this.startTime = builder.startTime;
029    this.endTime = builder.endTime;
030  }
031
032  /**
033   * コマンド名を取得
034   *
035   * @return コマンド名
036   */
037  public String getCommandName() {
038    return commandName;
039  }
040
041  /**
042   * 実行成功フラグを取得
043   *
044   * @return 実行が成功した場合true
045   */
046  public boolean isSuccess() {
047    return success;
048  }
049
050  /**
051   * 実行時間(ミリ秒)を取得
052   *
053   * @return 実行時間(ミリ秒)
054   */
055  public long getExecutionTimeMillis() {
056    return execMillis;
057  }
058
059  /**
060   * 入力バイト数を取得
061   *
062   * @return 入力バイト数
063   */
064  public long getInputBytes() {
065    return inputBytes;
066  }
067
068  /**
069   * 出力バイト数を取得
070   *
071   * @return 出力バイト数
072   */
073  public long getOutputBytes() {
074    return outputBytes;
075  }
076
077  /**
078   * エラーメッセージを取得(エラー時のみ)
079   *
080   * @return エラーメッセージ(エラーがない場合はnull)
081   */
082  public String getErrorMessage() {
083    return errorMessage;
084  }
085
086  /**
087   * 開始時刻を取得
088   *
089   * @return 開始時刻
090   */
091  public Instant getStartTime() {
092    return startTime;
093  }
094
095  /**
096   * 終了時刻を取得
097   *
098   * @return 終了時刻
099   */
100  public Instant getEndTime() {
101    return endTime;
102  }
103
104  /**
105   * 実行時間をDurationで取得
106   *
107   * @return 実行時間
108   */
109  public Duration getDuration() {
110    return Duration.between(startTime, endTime);
111  }
112
113  @Override
114  public String toString() {
115    return String.format(
116        "CommandResult{name='%s', success=%s, time=%dms, input=%db, output=%db%s}",
117        commandName,
118        success,
119        execMillis,
120        inputBytes,
121        outputBytes,
122        errorMessage != null ? ", error='" + errorMessage + "'" : "");
123  }
124
125  /** CommandResultのビルダークラス */
126  public static final class Builder {
127    /** Default constructor for CommandResult Builder. */
128    public Builder() {}
129
130    private String commandName;
131    private boolean success;
132    private long execMillis;
133    private long inputBytes;
134    private long outputBytes;
135    private String errorMessage;
136    private Instant startTime;
137    private Instant endTime;
138
139    /**
140     * コマンド名を設定
141     *
142     * @param commandName コマンド名
143     * @return Builderインスタンス
144     */
145    public Builder withCommandName(final String commandName) {
146      this.commandName = commandName;
147      return this;
148    }
149
150    /**
151     * 成功フラグを設定
152     *
153     * @param success 成功フラグ
154     * @return Builderインスタンス
155     */
156    public Builder withSuccess(final boolean success) {
157      this.success = success;
158      return this;
159    }
160
161    /**
162     * 実行時間を設定
163     *
164     * @param execMillis 実行時間(ミリ秒)
165     * @return Builderインスタンス
166     */
167    public Builder withExecMillis(final long execMillis) {
168      this.execMillis = execMillis;
169      return this;
170    }
171
172    /**
173     * 入力バイト数を設定
174     *
175     * @param inputBytes 入力バイト数
176     * @return Builderインスタンス
177     */
178    public Builder withInputBytes(final long inputBytes) {
179      this.inputBytes = inputBytes;
180      return this;
181    }
182
183    /**
184     * 出力バイト数を設定
185     *
186     * @param outputBytes 出力バイト数
187     * @return Builderインスタンス
188     */
189    public Builder withOutputBytes(final long outputBytes) {
190      this.outputBytes = outputBytes;
191      return this;
192    }
193
194    /**
195     * エラーメッセージを設定
196     *
197     * @param errorMessage エラーメッセージ
198     * @return Builderインスタンス
199     */
200    public Builder withErrorMessage(final String errorMessage) {
201      this.errorMessage = errorMessage;
202      return this;
203    }
204
205    /**
206     * 開始時刻を設定
207     *
208     * @param startTime 開始時刻
209     * @return Builderインスタンス
210     */
211    public Builder withStartTime(final Instant startTime) {
212      this.startTime = startTime;
213      return this;
214    }
215
216    /**
217     * 終了時刻を設定
218     *
219     * @param endTime 終了時刻
220     * @return Builderインスタンス
221     */
222    public Builder withEndTime(final Instant endTime) {
223      this.endTime = endTime;
224      return this;
225    }
226
227    /**
228     * CommandResultインスタンスを生成
229     *
230     * @return CommandResultインスタンス
231     */
232    public CommandResult build() {
233      return new CommandResult(this);
234    }
235  }
236
237  /**
238   * 成功結果を作成するヘルパーメソッド
239   *
240   * @param commandName コマンド名
241   * @param executionTime 実行時間(ミリ秒)
242   * @param inputBytes 入力バイト数
243   * @param outputBytes 出力バイト数
244   * @param startTime 開始時刻
245   * @param endTime 終了時刻
246   * @return 成功結果のCommandResult
247   */
248  public static CommandResult success(
249      final String commandName,
250      final long executionTime,
251      final long inputBytes,
252      final long outputBytes,
253      final Instant startTime,
254      final Instant endTime) {
255    return new Builder()
256        .withCommandName(commandName)
257        .withSuccess(true)
258        .withExecMillis(executionTime)
259        .withInputBytes(inputBytes)
260        .withOutputBytes(outputBytes)
261        .withStartTime(startTime)
262        .withEndTime(endTime)
263        .build();
264  }
265
266  /**
267   * 失敗結果を作成するヘルパーメソッド
268   *
269   * @param commandName コマンド名
270   * @param executionTime 実行時間(ミリ秒)
271   * @param errorMessage エラーメッセージ
272   * @param startTime 開始時刻
273   * @param endTime 終了時刻
274   * @return 失敗結果のCommandResult
275   */
276  public static CommandResult failure(
277      final String commandName,
278      final long executionTime,
279      final String errorMessage,
280      final Instant startTime,
281      final Instant endTime) {
282    return new Builder()
283        .withCommandName(commandName)
284        .withSuccess(false)
285        .withExecMillis(executionTime)
286        .withErrorMessage(errorMessage)
287        .withStartTime(startTime)
288        .withEndTime(endTime)
289        .build();
290  }
291}