// 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.devtools.coverageoutputgenerator.Constants.DELIMITER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_BRANCH_MARKER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_BRANCH_NOTEXEC;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_BRANCH_NOTTAKEN;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_BRANCH_TAKEN;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_CWD_MARKER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_FILE_MARKER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_FUNCTION_MARKER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_LINE_MARKER;
import static com.google.devtools.coverageoutputgenerator.Constants.GCOV_VERSION_MARKER;
import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A {@link Parser} for gcov intermediate format. See the flag {@code --intermediate-format} in <a
 * href="https://gcc.gnu.org/onlinedocs/gcc/Invoking-gcov.html">gcov documentation</a>.
 */
public class GcovParser {

  private static final Logger logger = Logger.getLogger(GcovParser.class.getName());
  private List<SourceFileCoverage> allSourceFiles;
  private final InputStream inputStream;
  private SourceFileCoverage currentSourceFileCoverage;

  private GcovParser(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  public static List<SourceFileCoverage> parse(InputStream inputStream) throws IOException {
    return new GcovParser(inputStream).parse();
  }

  private List<SourceFileCoverage> parse() throws IOException {
    allSourceFiles = new ArrayList<>();
    boolean malformedInput = false;
    try (BufferedReader bufferedReader =
        new BufferedReader(new InputStreamReader(inputStream, UTF_8))) {
      String line;
      // TODO(bazel-team): This is susceptible to OOM if the input file is too large and doesn't
      // contain any newlines.
      while ((line = bufferedReader.readLine()) != null) {
        if (!parseLine(line)) {
          malformedInput = true;
        }
      }
      bufferedReader.close();
    }
    endSourceFile();
    if (malformedInput) {
      logger.log(
          Level.WARNING,
          "gcov intermediate input was malformed, some lines might not have been parsed. "
              + "Check the previous log entries for more information.");
    }
    return allSourceFiles;
  }

  /**
   * Merges {@code currentSourceFileCoverage} into {@code allSourceFilesCoverageData} and resets
   * {@code currentSourceFileCoverage} to null.
   */
  private void endSourceFile() {
    if (currentSourceFileCoverage == null) {
      return;
    }
    allSourceFiles.add(currentSourceFileCoverage);
    currentSourceFileCoverage = null;
  }

  private boolean parseLine(String line) {
    if (line.isEmpty()) {
      return true;
    }
    if (line.startsWith(GCOV_FILE_MARKER)) {
      endSourceFile();
      return parseSource(line);
    }
    if (line.startsWith(GCOV_FUNCTION_MARKER)) {
      return parseFunction(line);
    }
    if (line.startsWith(GCOV_LINE_MARKER)) {
      return parseLCount(line);
    }
    if (line.startsWith(GCOV_BRANCH_MARKER)) {
      return parseBranch(line);
    }
    if (line.startsWith(GCOV_VERSION_MARKER) || line.startsWith(GCOV_CWD_MARKER)) {
      // Ignore these fields for now as they are not necessary.
      return true;
    }
    logger.log(
        Level.WARNING,
        "Line <" + line + "> does not respect the gcov intermediate format and was ignored.");
    return false;
  }

  private boolean parseSource(String line) {
    String sourcefile = line.substring(GCOV_FILE_MARKER.length());
    if (sourcefile.isEmpty()) {
      logger.log(Level.WARNING, "gcov info doesn't contain source file name on line: " + line);
      return false;
    }
    currentSourceFileCoverage = new SourceFileCoverage(sourcefile);
    return true;
  }

  /**
   * Valid lines: function:start_line_number,end_line_number,execution_count,function_name
   * function:start_line_number,execution_count,function_name
   */
  private boolean parseFunction(String line) {
    String lineContent = line.substring(GCOV_FUNCTION_MARKER.length());
    String[] items = lineContent.split(DELIMITER, -1);
    if (items.length != 4 && items.length != 3) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    try {
      // Ignore end_line_number since it's redundant information.
      int startLine = Integer.parseInt(items[0]);
      int execCount = items.length == 4 ? Integer.parseInt(items[2]) : Integer.parseInt(items[1]);
      String functionName = items.length == 4 ? items[3] : items[2];
      currentSourceFileCoverage.addLineNumber(functionName, startLine);
      currentSourceFileCoverage.addFunctionExecution(functionName, execCount);
    } catch (NumberFormatException e) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    return true;
  }

  /**
   * Valid lines: lcount:line number,execution_count,has_unexecuted_block lcount:line
   * number,execution_count
   */
  private boolean parseLCount(String line) {
    String lineContent = line.substring(GCOV_LINE_MARKER.length());
    String[] items = lineContent.split(DELIMITER, -1);
    if (items.length != 3 && items.length != 2) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    try {
      // Ignore has_unexecuted_block since it's not used.
      int lineNr = Integer.parseInt(items[0]);
      int execCount = Integer.parseInt(items[1]);
      currentSourceFileCoverage.addLine(lineNr, LineCoverage.create(lineNr, execCount, null));
    } catch (NumberFormatException e) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    return true;
  }

  // branch:line_number,branch_coverage_type
  private boolean parseBranch(String line) {
    String lineContent = line.substring(GCOV_BRANCH_MARKER.length());
    String[] items = lineContent.split(DELIMITER, -1);
    if (items.length != 2) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    try {
      // Ignore has_unexecuted_block since it's not used.
      int lineNr = Integer.parseInt(items[0]);
      String type = items[1];
      int execCount;
      switch (type) {
        case GCOV_BRANCH_NOTEXEC:
          execCount = 0;
          break;
        case GCOV_BRANCH_NOTTAKEN:
        case GCOV_BRANCH_TAKEN:
          execCount = 1;
          break;
        default:
          logger.log(Level.WARNING, "gcov info contains invalid line " + line);
          return false;
      }
      currentSourceFileCoverage.addBranch(lineNr, BranchCoverage.create(lineNr, execCount));
    } catch (NumberFormatException e) {
      logger.log(Level.WARNING, "gcov info contains invalid line " + line);
      return false;
    }
    return true;
  }
}
