// Copyright 2019 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.exec;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.exec.Protos.File;
import com.google.devtools.build.lib.exec.Protos.SpawnExec;
import com.google.devtools.build.lib.util.io.MessageOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link StableSort}. */
@RunWith(JUnit4.class)
public final class StableSortTest {

  private static class ListOutput implements MessageOutputStream<SpawnExec> {
    public ArrayList<SpawnExec> list;

    ListOutput() {
      list = new ArrayList<>();
    }

    @Override
    public void write(SpawnExec m) throws IOException {
      list.add(checkNotNull(m));
    }

    @Override
    public void close() throws IOException {}
  }

  ArrayList<SpawnExec> testStableSort(List<SpawnExec> list) throws Exception {
    ListOutput o = new ListOutput();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (SpawnExec spawn : list) {
      spawn.writeDelimitedTo(baos);
    }
    InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());

    StableSort.stableSort(inputStream, o);
    return o.list;
  }

  private static SpawnExec.Builder createSpawnExecBuilder(
      List<String> inputs, List<String> outputs) {
    SpawnExec.Builder e = SpawnExec.newBuilder();
    for (String output : outputs) {
      e.addActualOutputsBuilder().setPath(output);
      e.addListedOutputs(output);
    }
    for (String s : inputs) {
      e.addInputs(File.newBuilder().setPath(s).build());
    }
    return e;
  }

  private static SpawnExec createSpawnExec(List<String> inputs, List<String> outputs) {
    return createSpawnExecBuilder(inputs, outputs).build();
  }

  @Test
  public void stableSortEmpty() throws Exception {
    List<SpawnExec> l = testStableSort(ImmutableList.of());
    assertThat(l).isEmpty();
  }

  @Test
  public void stableSortOne() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of(), ImmutableList.of("output"));
    List<SpawnExec> l = testStableSort(ImmutableList.of(e1));
    assertThat(l).containsExactly(e1).inOrder();
  }

  @Test
  public void stableSortTwo_unlinkedLexicographic() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("a"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("leaf2"), ImmutableList.of("b"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e1, e2));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_unlinkedLexicographic_reverse() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("leaf2"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e1, e2));
    assertThat(l).containsExactly(e2, e1).inOrder();
  }

  @Test
  public void stableSortTwo_linked() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e1, e2));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_linked_inputOrderDoesNotMatter() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e2, e1));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_oneOfMultipleInputs() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b1", "b2", "b3"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("b2"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e2, e1));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_manyOfMultipleInputs() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b1", "b2", "b3"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("b2", "b3"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e2, e1));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_IrrelevantInputs() throws Exception {
    SpawnExec e1 = createSpawnExec(ImmutableList.of("leaf1"), ImmutableList.of("b1", "b2", "b3"));
    SpawnExec e2 = createSpawnExec(ImmutableList.of("z", "b2", "1"), ImmutableList.of("a"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(e2, e1));
    assertThat(l).containsExactly(e1, e2).inOrder();
  }

  @Test
  public void stableSortTwo_ABC() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of(""), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of(""), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(a, b, c).inOrder();
  }

  @Test
  public void stableSortTwo_CBA() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(c, b, a).inOrder();
  }

  @Test
  public void stableSortTwo_ACB() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of(""), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("a", "c"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(a, c, b).inOrder();
  }

  @Test
  public void stableSortTwo_CAB() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(c, a, b).inOrder();
  }

  @Test
  public void stableSortTwo_CAB2() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("c1"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("c2"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c1", "c2"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(c, a, b).inOrder();
  }

  @Test
  public void stableSortTwo_CBAFED() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));
    SpawnExec d = createSpawnExec(ImmutableList.of("e"), ImmutableList.of("d"));
    SpawnExec e = createSpawnExec(ImmutableList.of("f"), ImmutableList.of("e"));
    SpawnExec f = createSpawnExec(ImmutableList.of(""), ImmutableList.of("f"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c, d, e, f));
    assertThat(l).containsExactly(c, b, a, f, e, d).inOrder();
  }

  @Test
  public void stableSortTwo_InterleavedPaths() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of(""), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of(""), ImmutableList.of("c"));
    SpawnExec d = createSpawnExec(ImmutableList.of("a"), ImmutableList.of("d"));
    SpawnExec e = createSpawnExec(ImmutableList.of("f"), ImmutableList.of("e"));
    SpawnExec f = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("f"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c, d, e, f));
    assertThat(l).containsExactly(b, c, a, d, f, e).inOrder();
  }

  @Test
  public void stableSortTwo_ManyDependencies() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("b", "c", "f"), ImmutableList.of("a"));
    SpawnExec b = createSpawnExec(ImmutableList.of("d", "e"), ImmutableList.of("b"));
    SpawnExec c = createSpawnExec(ImmutableList.of("e", "d", "f"), ImmutableList.of("c"));
    SpawnExec d = createSpawnExec(ImmutableList.of(""), ImmutableList.of("d"));
    SpawnExec e = createSpawnExec(ImmutableList.of("f"), ImmutableList.of("e"));
    SpawnExec f = createSpawnExec(ImmutableList.of(""), ImmutableList.of("f"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c, d, e, f));
    assertThat(l).containsExactly(d, f, e, b, c, a).inOrder();
  }

  @Test
  public void stableSort_NoOutputs() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("a"), ImmutableList.of());
    SpawnExec b = createSpawnExec(ImmutableList.of("b"), ImmutableList.of());

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b));
    assertThat(l).containsExactly(a, b).inOrder();
  }

  @Test
  public void stableSort_NoOutputs_reversed() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("a"), ImmutableList.of());
    SpawnExec b = createSpawnExec(ImmutableList.of("b"), ImmutableList.of());

    List<SpawnExec> l = testStableSort(ImmutableList.of(b, a));
    assertThat(l).containsExactly(a, b).inOrder();
  }

  @Test
  public void stableSort_ListedOutputs() throws Exception {

    SpawnExec a =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("a"))
            .addCommandArgs("a")
            .build();
    SpawnExec b =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("b").build();
    SpawnExec c =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("c"))
            .addCommandArgs("c")
            .build();
    SpawnExec d =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("d"))
            .addCommandArgs("d")
            .build();
    SpawnExec e =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("e").build();
    SpawnExec f =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("f").build();

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c, d, e, f));
    assertThat(l)
        .containsExactly(
            // sorted elements with actual outputs
            a,
            c,
            d,
            // sorted elements without listed outputs
            b,
            e,
            f)
        .inOrder();
  }

  @Test
  public void stableSort_ListedOutputs_reordered() throws Exception {
    SpawnExec a =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("a"))
            .addCommandArgs("a")
            .build();
    SpawnExec b =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("b").build();
    SpawnExec c =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("c"))
            .addCommandArgs("c")
            .build();
    SpawnExec d =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("d"))
            .addCommandArgs("d")
            .build();
    SpawnExec e =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("e").build();
    SpawnExec f =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("f").build();

    // Reordering the input from the previous test does not change the resulting order
    List<SpawnExec> l = testStableSort(ImmutableList.of(f, e, d, c, b, a));
    assertThat(l)
        .containsExactly(
            // sorted elements with actual outputs
            a,
            c,
            d,
            // sorted elements without listed outputs
            b,
            e,
            f)
        .inOrder();
  }

  @Test
  public void stableSort_ListedOutputs_dependencies() throws Exception {
    // Dependencies are respected
    SpawnExec a =
        createSpawnExecBuilder(ImmutableList.of("d"), ImmutableList.of("a"))
            .addCommandArgs("a")
            .build();
    SpawnExec b =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("b").build();
    SpawnExec c =
        createSpawnExecBuilder(ImmutableList.of("d"), ImmutableList.of("c"))
            .addCommandArgs("c")
            .build();
    SpawnExec d =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of("d"))
            .addCommandArgs("d")
            .build();
    SpawnExec e =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("e").build();
    SpawnExec f =
        createSpawnExecBuilder(ImmutableList.of(), ImmutableList.of()).addCommandArgs("f").build();

    List<SpawnExec> l = testStableSort(ImmutableList.of(f, e, d, c, b, a));
    assertThat(l).containsExactly(d, a, c, b, e, f).inOrder();
  }

  @Test
  public void stableSort_execsWithDuplicateOutputs() throws Exception {
    SpawnExec a = createSpawnExec(ImmutableList.of("a"), ImmutableList.of("c"));
    SpawnExec b = createSpawnExec(ImmutableList.of("b"), ImmutableList.of("c"));
    SpawnExec c = createSpawnExec(ImmutableList.of("c"), ImmutableList.of("d"));

    List<SpawnExec> l = testStableSort(ImmutableList.of(a, b, c));
    assertThat(l).containsExactly(a, b, c).inOrder();
  }
}
