// Copyright 2020 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 com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;

/**
 * A {@link Parser} for gcov intermediate json format introduced in GCC 9.1. See the flag {@code
 * --intermediate-format} in <a
 * href="https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Invoking-Gcov.html">gcov documentation</a>.
 */
public class GcovJsonParser {
  private static final Logger logger = Logger.getLogger(GcovJsonParser.class.getName());
  private final InputStream inputStream;

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

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

  private List<SourceFileCoverage> parse() throws IOException {
    ArrayList<SourceFileCoverage> allSourceFiles = new ArrayList<>();
    try (InputStream gzipStream = new GZIPInputStream(inputStream)) {
      ByteArrayOutputStream contents = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      int length;
      while ((length = gzipStream.read(buffer)) != -1) {
        contents.write(buffer, 0, length);
      }
      Gson gson = new Gson();
      GcovJsonFormat document = gson.fromJson(contents.toString(), GcovJsonFormat.class);
      if (!document.format_version.equals("1")) {
        logger.log(
            Level.WARNING,
            "Expect GCov JSON format version 1, got format version " + document.format_version);
      }
      for (GcovJsonFile file : document.files) {
        SourceFileCoverage currentFileCoverage = new SourceFileCoverage(file.file);
        for (GcovJsonFunction function : file.functions) {
          currentFileCoverage.addLineNumber(function.name, function.start_line);
          currentFileCoverage.addFunctionExecution(function.name, function.execution_count);
        }
        for (GcovJsonLine line : file.lines) {
          currentFileCoverage.addLine(
              line.line_number, LineCoverage.create(line.line_number, line.count, null));
          for (GcovJsonBranch branch : line.branches) {
            currentFileCoverage.addBranch(
                line.line_number, BranchCoverage.create(line.line_number, branch.count));
          }
        }
        allSourceFiles.add(currentFileCoverage);
      }
    }

    return allSourceFiles;
  }

  // Classes for the Gson data mapper representing the structure of the GCov JSON format
  // These do not follow the Java naming styleguide as they need to match the JSON field names
  // Documentation can be found in GCov's manpage, of which the source is available at
  // https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/doc/gcov.texi;h=dcdd7831ff063483d43e5347af0b67083c85ecc4;hb=4212a6a3e44f870412d9025eeb323fd4f50a61da#l184

  static class GcovJsonFormat {
    String gcc_version;
    GcovJsonFile[] files;
    String format_version;
    String current_working_directory;
    String data_file;
  }

  static class GcovJsonFile {
    String file;
    GcovJsonFunction[] functions;
    GcovJsonLine[] lines;
  }

  static class GcovJsonFunction {
    int blocks;
    int end_column;
    int start_line;
    String name;
    int blocks_executed;
    int execution_count;
    String demangled_name;
    int start_column;
    int end_line;
  }

  static class GcovJsonLine {
    GcovJsonBranch[] branches;
    int count;
    int line_number;
    boolean unexecuted_block;
    String function_name;
  }

  static class GcovJsonBranch {
    boolean fallthrough;
    int count;

    @SerializedName("throw")
    boolean _throw;
  }
}
