// 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 com.google.common.collect.ImmutableList;
import java.util.Map;
import java.util.TreeMap;

/**
 * Helper class for creating and parsing lcov tracefiles and the necessary data structured used by
 * {@code LcovMerger}.
 *
 * <p>The tests are floating around 2 main tracefiles (numbered with 1 and 2 throughout the tests
 * code base). The tracefiles refer the same source file with different coverage data, making them
 * good candidates for being merged.
 *
 * <p>There are multiple static variables defined for information extracted from each of
 * tracefile{1,2} (e.g. the number of lines found, the number of functions hit, lines execution).
 *
 * <p>Additionally, the 2 tracefiles may be used in tests multiple times with different source
 * filenames so they could be considered as different entries in the merged tracefile.
 */
public class LcovMergerTestUtils {

  // The content of tracefile1.
  static final ImmutableList<String> TRACEFILE1 =
      ImmutableList.of(
          "SF:SOURCE_FILENAME",
          "FN:10,file1-func1",
          "FN:20,file1-func2",
          "FN:25,file1-func3",
          "FNDA:3,file1-func1",
          "FNDA:5,file1-func2",
          "FNDA:0,file1-func3",
          "FNF:3",
          "FNH:2",
          "DA:10,3",
          "DA:11,3",
          "DA:12,30",
          "DA:13,30",
          "DA:15,3",
          "DA:16,0",
          "DA:17,0",
          "DA:19,3",
          "DA:20,5",
          "DA:21,5",
          "DA:22,5",
          "DA:23,5",
          "DA:25,0",
          "DA:26,0",
          "LH:10",
          "LF:14",
          "end_of_record");

  static final ImmutableList<String> TRACEFILE1_DIFFERENT_NAME =
      ImmutableList.of(
          "SF:DIFFERENT_SOURCE_FILENAME",
          "FN:10,file1-func1",
          "FN:20,file1-func2",
          "FN:25,file1-func3",
          "FNDA:3,file1-func1",
          "FNDA:5,file1-func2",
          "FNDA:0,file1-func3",
          "FNF:3",
          "FNH:2",
          "DA:10,3",
          "DA:11,3",
          "DA:12,30",
          "DA:13,30",
          "DA:15,3",
          "DA:16,0",
          "DA:17,0",
          "DA:19,3",
          "DA:20,5",
          "DA:21,5",
          "DA:22,5",
          "DA:23,5",
          "DA:25,0",
          "DA:26,0",
          "LH:10",
          "LF:14",
          "end_of_record");

  // The content of tracefile2.
  static final ImmutableList<String> TRACEFILE2 =
      ImmutableList.of(
          "SF:SOURCE_FILENAME",
          "FN:10,file1-func1",
          "FN:20,file1-func2",
          "FN:25,file1-func3",
          "FNDA:2,file1-func1",
          "FNDA:3,file1-func2",
          "FNDA:2,file1-func3",
          "FNF:3",
          "FNH:3",
          "DA:10,2",
          "DA:11,2",
          "DA:12,20",
          "DA:13,20",
          "DA:15,2",
          "DA:16,2",
          "DA:17,2",
          "DA:19,0",
          "DA:20,3",
          "DA:21,3",
          "DA:22,3",
          "DA:23,3",
          "DA:25,2",
          "DA:26,2",
          "LH:13",
          "LF:14",
          "end_of_record");

  // The content of a tracefile after tracefile1 and tracefile2 were merged together.
  static final ImmutableList<String> MERGED_TRACEFILE =
      ImmutableList.of(
          "SF:SOURCE_FILENAME",
          "FN:10,file1-func1",
          "FN:20,file1-func2",
          "FN:25,file1-func3",
          "FNDA:5,file1-func1",
          "FNDA:8,file1-func2",
          "FNDA:2,file1-func3",
          "FNF:3",
          "FNH:3",
          "DA:10,5",
          "DA:11,5",
          "DA:12,50",
          "DA:13,50",
          "DA:15,5",
          "DA:16,2",
          "DA:17,2",
          "DA:19,3",
          "DA:20,8",
          "DA:21,8",
          "DA:22,8",
          "DA:23,8",
          "DA:25,2",
          "DA:26,2",
          "LH:14",
          "LF:14",
          "end_of_record");

  static final String SOURCE_FILENAME = "SOURCE_FILENAME";
  static final int NR_FUNCTIONS_FOUND = 3;
  static final int NR_FUNCTIONS_HIT_TRACEFILE1 = 2;
  static final int NR_FUNCTIONS_HIT_TRACEFILE2 = 3;

  static final String FUNC_1 = "file1-func1";
  static final int FUNC_1_LINE_NR = 10;
  static final int FUNC_1_NR_EXECUTED_LINES_TRACEFILE1 = 3;
  static final int FUNC_1_NR_EXECUTED_LINES_TRACEFILE2 = 2;

  static final String FUNC_2 = "file1-func2";
  static final int FUNC_2_LINE_NR = 20;
  static final int FUNC_2_NR_EXECUTED_LINES_TRACEFILE1 = 5;
  static final int FUNC_2_NR_EXECECUTED_LINES_TRACEFILE2 = 3;

  static final String FUNC_3 = "file1-func3";
  static final int FUNC_3_LINE_NR = 25;
  static final int FUNC_3_NR_EXECUTED_LINES_TRACEFILE1 = 0;
  static final int FUNC_3_NR_EXECUTED_LINES_TRACEFILE2 = 2;

  static final int NR_LINES_FOUND = 14;
  static final int NR_LINES_HIT_TRACEFILE1 = 10;
  static final int NR_LINES_HIT_TRACEFILE2 = 13;

  static final int MAX_LINES_IN_FILE = 27;

  static int[] createLinesExecution1() {
    int[] lineExecutionCountForTracefile = new int[MAX_LINES_IN_FILE];
    for (int i = 0; i < MAX_LINES_IN_FILE; ++i) {
      lineExecutionCountForTracefile[i] = -1; // no corresponding DA line for line i
    }

    lineExecutionCountForTracefile[10] = 3; // DA:10,3
    lineExecutionCountForTracefile[11] = 3; // DA:11,3
    lineExecutionCountForTracefile[12] = 30; // DA:12,30
    lineExecutionCountForTracefile[13] = 30; // DA:13,30
    lineExecutionCountForTracefile[15] = 3; // DA:15,3
    lineExecutionCountForTracefile[16] = 0; // DA:16,0
    lineExecutionCountForTracefile[17] = 0; // DA:17,0
    lineExecutionCountForTracefile[19] = 3; // DA:19,3
    lineExecutionCountForTracefile[20] = 5; // DA:20,5
    lineExecutionCountForTracefile[21] = 5; // DA:21,5
    lineExecutionCountForTracefile[22] = 5; // DA:22,5
    lineExecutionCountForTracefile[23] = 5; // DA:23,5
    lineExecutionCountForTracefile[25] = 0; // DA:25,0
    lineExecutionCountForTracefile[26] = 0; // DA:26,0
    return lineExecutionCountForTracefile;
  }

  static int[] createLinesExecution2() {
    int[] lineExecutionCountForTracefile = new int[MAX_LINES_IN_FILE];
    for (int i = 0; i < MAX_LINES_IN_FILE; ++i) {
      lineExecutionCountForTracefile[i] = -1; // no corresponding DA line for line i
    }

    lineExecutionCountForTracefile[10] = 2; // DA:10,2
    lineExecutionCountForTracefile[11] = 2; // DA:11,2
    lineExecutionCountForTracefile[12] = 20; // DA:12,20
    lineExecutionCountForTracefile[13] = 20; // DA:13,20
    lineExecutionCountForTracefile[15] = 2; // DA:15,2
    lineExecutionCountForTracefile[16] = 2; // DA:16,2
    lineExecutionCountForTracefile[17] = 2; // DA:17,2
    lineExecutionCountForTracefile[19] = 0; // DA:19,0
    lineExecutionCountForTracefile[20] = 3; // DA:20,3
    lineExecutionCountForTracefile[21] = 3; // DA:21,3
    lineExecutionCountForTracefile[22] = 3; // DA:22,3
    lineExecutionCountForTracefile[23] = 3; // DA:23,3
    lineExecutionCountForTracefile[25] = 2; // DA:25,2
    lineExecutionCountForTracefile[26] = 2; // DA:26,2
    return lineExecutionCountForTracefile;
  }

  static SourceFileCoverage createSourceFile1(int[] lineExecutionCountForTracefile) {
    return createSourceFile1(SOURCE_FILENAME, lineExecutionCountForTracefile);
  }

  // Create source file coverage data, excluding branch coverage
  static SourceFileCoverage createSourceFile1(String sourceFilename, int[] lineExecutionCount) {
    SourceFileCoverage sourceFile = new SourceFileCoverage(sourceFilename);

    sourceFile.addLineNumber(FUNC_1, FUNC_1_LINE_NR);
    sourceFile.addFunctionExecution(FUNC_1, FUNC_1_NR_EXECUTED_LINES_TRACEFILE1);

    sourceFile.addLineNumber(FUNC_2, FUNC_2_LINE_NR);
    sourceFile.addFunctionExecution(FUNC_2, FUNC_2_NR_EXECUTED_LINES_TRACEFILE1);

    sourceFile.addLineNumber(FUNC_3, FUNC_3_LINE_NR);
    sourceFile.addFunctionExecution(FUNC_3, FUNC_3_NR_EXECUTED_LINES_TRACEFILE1);

    for (int line = FUNC_1_LINE_NR; line < MAX_LINES_IN_FILE; line++) {
      if (lineExecutionCount[line] >= 0) {
        sourceFile.addLine(line, LineCoverage.create(line, lineExecutionCount[line], null));
      }
    }

    return sourceFile;
  }

  // Create source file coverage data, excluding branch coverage
  static SourceFileCoverage createSourceFile2(int[] lineExecutionCount) {
    SourceFileCoverage sourceFileCoverage = new SourceFileCoverage(SOURCE_FILENAME);

    sourceFileCoverage.addLineNumber(FUNC_1, FUNC_1_LINE_NR);
    sourceFileCoverage.addFunctionExecution(FUNC_1, FUNC_1_NR_EXECUTED_LINES_TRACEFILE2);

    sourceFileCoverage.addLineNumber(FUNC_2, FUNC_2_LINE_NR);
    sourceFileCoverage.addFunctionExecution(FUNC_2, FUNC_2_NR_EXECECUTED_LINES_TRACEFILE2);

    sourceFileCoverage.addLineNumber(FUNC_3, FUNC_3_LINE_NR);
    sourceFileCoverage.addFunctionExecution(FUNC_3, FUNC_3_NR_EXECUTED_LINES_TRACEFILE2);

    for (int line = FUNC_1_LINE_NR; line < MAX_LINES_IN_FILE; line++) {
      if (lineExecutionCount[line] >= 0) {
        sourceFileCoverage.addLine(line, LineCoverage.create(line, lineExecutionCount[line], null));
      }
    }
    return sourceFileCoverage;
  }

  private static void assertLinesExecution_tracefile1(Map<Integer, LineCoverage> lines) {
    int[] lineExecution = createLinesExecution1();

    assertThat(lines.size()).isEqualTo(NR_LINES_FOUND);

    for (int line = 10; line < lineExecution.length; line++) {
      if (lineExecution[line] >= 0) {
        LineCoverage lineCoverage = lines.get(line);
        assertThat(lineCoverage.executionCount()).isEqualTo(lineExecution[line]);
        assertThat(lineCoverage.lineNumber()).isEqualTo(line);
        assertThat(lineCoverage.checksum()).isNull();
      }
    }
  }

  private static void assertLines_tracefile2(Map<Integer, LineCoverage> lines) {
    int[] lineExecution = createLinesExecution2();

    assertThat(lines.size()).isEqualTo(NR_LINES_FOUND);

    for (int lineIndex = 10; lineIndex < lineExecution.length; lineIndex++) {
      if (lineExecution[lineIndex] >= 0) {
        LineCoverage line = lines.get(lineIndex);
        assertThat(line.executionCount()).isEqualTo(lineExecution[lineIndex]);
        assertThat(line.lineNumber()).isEqualTo(lineIndex);
        assertThat(line.checksum()).isNull();
      }
    }
  }

  static void assertTracefile1(SourceFileCoverage sourceFile) {
    Map<String, Integer> lineNumbers = sourceFile.getLineNumbers();
    assertThat(lineNumbers.size()).isEqualTo(3);
    assertThat(lineNumbers.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(lineNumbers.get(FUNC_1)).isEqualTo(FUNC_1_LINE_NR);
    assertThat(lineNumbers.get(FUNC_2)).isEqualTo(FUNC_2_LINE_NR);
    assertThat(lineNumbers.get(FUNC_3)).isEqualTo(FUNC_3_LINE_NR);

    Map<String, Integer> functionsExecution = sourceFile.getFunctionsExecution();
    assertThat(functionsExecution.size()).isEqualTo(3);
    assertThat(functionsExecution.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(functionsExecution.get(FUNC_1)).isEqualTo(FUNC_1_NR_EXECUTED_LINES_TRACEFILE1);
    assertThat(functionsExecution.get(FUNC_2)).isEqualTo(FUNC_2_NR_EXECUTED_LINES_TRACEFILE1);
    assertThat(functionsExecution.get(FUNC_3)).isEqualTo(FUNC_3_NR_EXECUTED_LINES_TRACEFILE1);

    assertLinesExecution_tracefile1(sourceFile.getLines());

    assertThat(sourceFile.nrOfInstrumentedLines()).isEqualTo(14);
    assertThat(sourceFile.nrOfLinesWithNonZeroExecution()).isEqualTo(10);
  }

  static void assertTracefile2(SourceFileCoverage sourceFile) {
    Map<String, Integer> lineNumbers = sourceFile.getLineNumbers();
    assertThat(lineNumbers.size()).isEqualTo(3);
    assertThat(lineNumbers.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(lineNumbers.get(FUNC_1)).isEqualTo(FUNC_1_LINE_NR);
    assertThat(lineNumbers.get(FUNC_2)).isEqualTo(FUNC_2_LINE_NR);
    assertThat(lineNumbers.get(FUNC_3)).isEqualTo(FUNC_3_LINE_NR);

    Map<String, Integer> functionsExecution = sourceFile.getFunctionsExecution();
    assertThat(functionsExecution.size()).isEqualTo(3);
    assertThat(functionsExecution.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(functionsExecution.get(FUNC_1)).isEqualTo(FUNC_1_NR_EXECUTED_LINES_TRACEFILE2);
    assertThat(functionsExecution.get(FUNC_2)).isEqualTo(FUNC_2_NR_EXECECUTED_LINES_TRACEFILE2);
    assertThat(functionsExecution.get(FUNC_3)).isEqualTo(FUNC_3_NR_EXECUTED_LINES_TRACEFILE2);

    assertLines_tracefile2(sourceFile.getLines());

    assertThat(sourceFile.nrOfInstrumentedLines()).isEqualTo(14);
    assertThat(sourceFile.nrOfLinesWithNonZeroExecution()).isEqualTo(13);
  }

  static void assertMergedLineNumbers(TreeMap<String, Integer> lineNumbers) {
    assertThat(lineNumbers.size()).isEqualTo(3);
    assertThat(lineNumbers.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(lineNumbers.get(FUNC_1)).isEqualTo(FUNC_1_LINE_NR);
    assertThat(lineNumbers.get(FUNC_2)).isEqualTo(FUNC_2_LINE_NR);
    assertThat(lineNumbers.get(FUNC_3)).isEqualTo(FUNC_3_LINE_NR);
  }

  static void assertMergedFunctionsExecution(TreeMap<String, Integer> functionsExecution) {
    assertThat(functionsExecution.size()).isEqualTo(3);
    assertThat(functionsExecution.keySet()).containsAtLeast(FUNC_1, FUNC_2, FUNC_3);
    assertThat(functionsExecution.get(FUNC_1))
        .isEqualTo(FUNC_1_NR_EXECUTED_LINES_TRACEFILE1 + FUNC_1_NR_EXECUTED_LINES_TRACEFILE2);
    assertThat(functionsExecution.get(FUNC_2))
        .isEqualTo(FUNC_2_NR_EXECUTED_LINES_TRACEFILE1 + FUNC_2_NR_EXECECUTED_LINES_TRACEFILE2);
    assertThat(functionsExecution.get(FUNC_3))
        .isEqualTo(FUNC_3_NR_EXECUTED_LINES_TRACEFILE1 + FUNC_3_NR_EXECUTED_LINES_TRACEFILE2);
  }

  static void assertMergedLines(
      Map<Integer, LineCoverage> lines, int[] linesExecution1, int[] linesExecution2) {
    assertThat(lines.size()).isEqualTo(14);

    for (int lineIndex = 10; lineIndex < MAX_LINES_IN_FILE; ++lineIndex) {
      int totalExecutionCount = 0;
      boolean wasInstrumented = false;
      if (linesExecution1[lineIndex] >= 0) {
        totalExecutionCount += linesExecution1[lineIndex];
        wasInstrumented = true;
      }
      if (linesExecution2[lineIndex] >= 0) {
        totalExecutionCount += linesExecution2[lineIndex];
        wasInstrumented = true;
      }
      if (wasInstrumented) {
        LineCoverage line = lines.get(lineIndex);
        assertThat(line.executionCount()).isEqualTo(totalExecutionCount);
        assertThat(line.lineNumber()).isEqualTo(lineIndex);
        assertThat(line.checksum()).isNull();
      }
    }
  }

  static void assertMergedSourceFile(
      SourceFileCoverage merged, int[] linesExecution1, int[] linesExecution2) {
    assertMergedLineNumbers(merged.getLineNumbers());
    assertMergedFunctionsExecution(merged.getFunctionsExecution());
    assertMergedLines(merged.getLines(), linesExecution1, linesExecution2);

    assertThat(merged.nrFunctionsFound()).isEqualTo(NR_FUNCTIONS_FOUND);
    assertThat(merged.nrFunctionsHit()).isEqualTo(NR_FUNCTIONS_FOUND);
    assertThat(merged.nrOfLinesWithNonZeroExecution()).isEqualTo(14);
    assertThat(merged.nrOfInstrumentedLines()).isEqualTo(14);
  }
}
