// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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
//
//    http://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 com.google.devtools.build.lib.runtime;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import com.google.common.base.Strings;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestSpec;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link LineBufferedOutputStream} .
 */
@TestSpec(size = Suite.SMALL_TESTS)
@RunWith(JUnit4.class)
public class LineBufferedOutputStreamTest {
  private static class MockOutputStream extends OutputStream {
    private final List<String> writes = new ArrayList<>();
    private boolean throwException = false;

    @Override
    public void write(int byteAsInt) throws IOException {
      byte b = (byte) byteAsInt; // make sure we work with bytes in comparisons
      write(new byte[] {b}, 0, 1);
    }

    @Override
    public synchronized void write(byte[] b, int off, int inlen) throws IOException {
      writes.add(new String(b, off, inlen, StandardCharsets.UTF_8));
      if (throwException) {
        throwException = false;
        throw new IOException("thrown");
      }
    }
  }

  private List<String> lineBuffer(String... inputs) throws Exception {
    MockOutputStream mockOutputStream = new MockOutputStream();
    try (LineBufferedOutputStream cut = new LineBufferedOutputStream(mockOutputStream, 6)) {
      for (String input : inputs) {
        cut.write(input.getBytes(StandardCharsets.UTF_8));
      }
    }

    return mockOutputStream.writes;
  }

  @Test
  public void testLineBuffering() throws Exception {
    String large = Strings.repeat("a", 100);

    assertThat(lineBuffer("foo\nbar")).containsExactly("foo\n", "bar");
    assertThat(lineBuffer("foobarfoobar")).containsExactly("foobar", "foobar");
    assertThat(lineBuffer("fivey\none\n")).containsExactly("fivey\n", "one\n");
    assertThat(lineBuffer("sixish\none\n")).containsExactly("sixish", "\n", "one\n");
    assertThat(lineBuffer("s")).containsExactly("s");
    assertThat(lineBuffer("\n\n\n\n")).containsExactly("\n", "\n", "\n", "\n");
    assertThat(lineBuffer("foo\n\nbar\n")).containsExactly("foo\n", "\n", "bar\n");

    assertThat(lineBuffer("a", "a", large, large, "a")).containsExactly(
        "aa", large, large, "a");
  }

  @Test
  public void testIOErrorOnWrappedStream() throws Exception {
    MockOutputStream mos = new MockOutputStream();
    LineBufferedOutputStream cut = new LineBufferedOutputStream(mos, 4);
    mos.throwException = true;
    try {
      cut.write("aaaa".getBytes(StandardCharsets.UTF_8));
      fail("IOException expected");
    } catch (IOException e) {
      // Expected.
    }
    cut.write("a".getBytes(StandardCharsets.UTF_8));
    cut.close();
    assertThat(mos.writes).containsExactly("aaaa", "a");
  }
}
