// Copyright 2018 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.coverageoutputgenerator;

import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link GcovParser}. */
@RunWith(JUnit4.class)
public class GcovParserTest {

  private static final ImmutableList<String> GCOV_INFO_FILE =
      ImmutableList.of(
          "version: 8.1.0 20180103",
          "cwd:/home/gcc/testcase",
          "file:tmp.cpp",
          "function:7,7,0,_ZN3FooIcEC2Ev",
          "function:7,7,1,_ZN3FooIiEC2Ev",
          "function:8,8,0,_ZN3FooIcE3incEv",
          "function:8,8,2,_ZN3FooIiE3incEv",
          "function:18,37,1,main",
          "lcount:7,0,1",
          "lcount:7,1,0",
          "lcount:8,0,1",
          "lcount:8,2,0",
          "lcount:18,1,0",
          "lcount:21,1,0",
          "branch:21,taken",
          "branch:21,nottaken",
          "lcount:23,1,0",
          "branch:23,taken",
          "branch:23,nottaken",
          "lcount:24,1,0",
          "branch:24,taken",
          "branch:24,nottaken",
          "lcount:25,1,0",
          "lcount:27,11,0",
          "branch:27,taken",
          "branch:27,taken",
          "lcount:28,10,0",
          "lcount:30,1,1",
          "branch:30,nottaken",
          "branch:30,taken",
          "lcount:32,1,0",
          "branch:32,nottaken",
          "branch:32,taken",
          "lcount:33,0,1",
          "branch:33,notexec",
          "branch:33,notexec",
          "lcount:35,1,0",
          "branch:35,taken",
          "branch:35,nottaken",
          "lcount:36,1,0");

  private static final ImmutableList<String> GCOV_INFO_FILE2 =
      ImmutableList.of(
          "file:tmp.cpp",
          "function:7,0,_ZN3FooIcEC2Ev",
          "function:7,1,_ZN3FooIiEC2Ev",
          "function:8,0,_ZN3FooIcE3incEv",
          "function:8,2,_ZN3FooIiE3incEv",
          "function:18,1,main",
          "lcount:7,0",
          "lcount:7,1",
          "lcount:8,0",
          "lcount:8,2",
          "lcount:18,1",
          "lcount:21,1",
          "branch:21,taken",
          "branch:21,nottaken",
          "lcount:23,1",
          "branch:23,taken",
          "branch:23,nottaken",
          "lcount:24,1",
          "branch:24,taken",
          "branch:24,nottaken",
          "lcount:25,1",
          "lcount:27,11",
          "branch:27,taken",
          "branch:27,taken",
          "lcount:28,10",
          "lcount:30,1",
          "branch:30,nottaken",
          "branch:30,taken",
          "lcount:32,1",
          "branch:32,nottaken",
          "branch:32,taken",
          "lcount:33,0",
          "branch:33,notexec",
          "branch:33,notexec",
          "lcount:35,1",
          "branch:35,taken",
          "branch:35,nottaken",
          "lcount:36,1");

  @Test
  public void testParseInvalidFile() throws IOException {
    assertThat(GcovParser.parse(new ByteArrayInputStream("Invalid gcov file".getBytes(UTF_8))))
        .isEmpty();
  }

  @Test
  public void testParseTracefileWithOneSourcefile() throws IOException {
    List<SourceFileCoverage> sourceFiles =
        GcovParser.parse(
            new ByteArrayInputStream(Joiner.on("\n").join(GCOV_INFO_FILE).getBytes(UTF_8)));
    assertThat(sourceFiles).hasSize(1);
    assertGcovInfoFile(sourceFiles.get(0));
  }

  @Test
  public void testParseTracefilWithDifferentFormat() throws IOException {
    List<SourceFileCoverage> sourceFiles =
        GcovParser.parse(
            new ByteArrayInputStream(Joiner.on("\n").join(GCOV_INFO_FILE2).getBytes(UTF_8)));
    assertThat(sourceFiles).hasSize(1);
    assertGcovInfoFile(sourceFiles.get(0));
  }

  private void assertGcovInfoFile(SourceFileCoverage sourceFileCoverage) {
    assertThat(sourceFileCoverage.sourceFileName()).isEqualTo("tmp.cpp");

    assertThat(sourceFileCoverage.nrFunctionsFound()).isEqualTo(5);
    assertThat(sourceFileCoverage.nrFunctionsHit()).isEqualTo(3);
    assertThat(sourceFileCoverage.nrOfInstrumentedLines()).isEqualTo(14);
    assertThat(sourceFileCoverage.nrOfLinesWithNonZeroExecution()).isEqualTo(13);
    assertThat(sourceFileCoverage.nrBranchesFound()).isEqualTo(16);
    assertThat(sourceFileCoverage.nrBranchesHit()).isEqualTo(8);

    assertThat(sourceFileCoverage.getAllLineExecution())
        .containsExactly(
            LineCoverage.create(7, 1, null),
            LineCoverage.create(8, 2, null),
            LineCoverage.create(18, 1, null),
            LineCoverage.create(21, 1, null),
            LineCoverage.create(23, 1, null),
            LineCoverage.create(24, 1, null),
            LineCoverage.create(25, 1, null),
            LineCoverage.create(27, 11, null),
            LineCoverage.create(28, 10, null),
            LineCoverage.create(30, 1, null),
            LineCoverage.create(32, 1, null),
            LineCoverage.create(33, 0, null),
            LineCoverage.create(35, 1, null),
            LineCoverage.create(36, 1, null));

    assertThat(sourceFileCoverage.getAllBranches())
        .containsExactly(
            BranchCoverage.createWithBranch(21, "0", true, 1),
            BranchCoverage.createWithBranch(21, "1", true, 0),
            BranchCoverage.createWithBranch(23, "0", true, 1),
            BranchCoverage.createWithBranch(23, "1", true, 0),
            BranchCoverage.createWithBranch(24, "0", true, 1),
            BranchCoverage.createWithBranch(24, "1", true, 0),
            BranchCoverage.createWithBranch(27, "0", true, 1),
            BranchCoverage.createWithBranch(27, "1", true, 1),
            BranchCoverage.createWithBranch(30, "0", true, 0),
            BranchCoverage.createWithBranch(30, "1", true, 1),
            BranchCoverage.createWithBranch(32, "0", true, 0),
            BranchCoverage.createWithBranch(32, "1", true, 1),
            BranchCoverage.createWithBranch(33, "0", false, 0),
            BranchCoverage.createWithBranch(33, "1", false, 0),
            BranchCoverage.createWithBranch(35, "0", true, 1),
            BranchCoverage.createWithBranch(35, "1", true, 0));
  }
}
