<!--
  The res/js/fuzzer.js file must be included before this file.

  This in an HTML Import-able file that contains the definition
  of the following elements:

    <fuzzer-info-sk>

  This element will query /json/details for all of the detailed fuzz reports of a given file (passed in by query params) and displayed.
  This may be further scoped by function, line number and fuzz-type (either binary or api)

  To use this file import it:

    <link href="/res/imp/fuzzer-info-sk.html" rel="import" />

  Usage:

    <fuzzer-info-sk></fuzzer-info-sk>

  Properties:
    category: String.
    exclude: Array of String, all fuzzes that have one or more of these strings as a flag will not
        be shown.  This array must be sorted lexographically.
    include: Array of String, all fuzzes must have one or more of these strings as a flag to be
        shown.  This array must be sorted lexographically.

  Methods:
    None.

  Events:
    None.
-->

<link rel="import" href="/res/imp/bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">
<link rel="import" href="/res/common/imp/url-params-sk.html">

<link rel="import" href="fuzzer-collapse-file-sk.html">
<link rel="import" href="fuzzer-filter-sk.html">

<dom-module id="fuzzer-info-sk">
  <template>
    <iron-ajax auto url="/json/details"
      handle-as="json"
      params="[[_urlParams]]"
      last-response="{{_fuzzDetails}}">
    </iron-ajax>

    <template is="dom-repeat" items="[[_filteredFileDetails]]" as="file" sort="_byCount">
      <fuzzer-collapse-file-sk file="{{file}}"
          category="[[category]]"
          expand="[[_shouldExpand()]]">
      </fuzzer-collapse-file-sk>
    </template>
    <template is="dom-if" if="[[_isEmpty]]">
      <div>No results found (or server is still loading). Try refreshing this page later.</div>
    </template>

  </template>

  <script>
    Polymer({
      is: 'fuzzer-info-sk',

      properties: {
        architecture: {
          type: String,
          value: function() {
            return [];
          }
        },
        category: {
          type: String,
          value: "",
        },
        include: {
          type: Array,
          value: function() {
            return [];
          }
        },
        exclude: {
          type: Array,
          value: function() {
            return [];
          }
        },
        _fuzzDetails: {
          type: Array,
          value: function() {
            return [];
          },
        },
        _filteredFileDetails: {
          type: Array,
          computed: "_filter(_fuzzDetails, architecture.*, include.*, exclude.*)",
        },
        _isEmpty: {
          type: Boolean,
          computed: "_empty(_filteredFileDetails)",
        },
        _urlParams: {
          type: String,
          computed: "_getURLParams(category)",
        },
      },

      _byCount: function(a, b) {
        // Higher counts come first
        return b.count - a.count;
      },

      _empty: function(a) {
        return !a || !a.length;
      },

      _filter: function(fuzzDetails){
        if (this._empty(fuzzDetails)) {
          return [];
        }
        var exclude = this.exclude || [];
        var include = this.include || [];
        var architecture = this.architecture || [];
        var fileDetails = this._group(fuzzDetails);

        // make a fresh copy of the data.  This way, we can just completely replace the array
        // without having to do Polymer's special array manipulation.
        var retVal = JSON.parse(JSON.stringify(fileDetails));

        retVal.forEach(function(file){
          var fileCount = 0;
          file.byFunction.forEach(function(func) {
            var funcCount = 0;
            func.byLineNumber.forEach(function(line) {
              line.reports = line.reports.filter(function(report) {
                if (architecture.length > 0 && architecture.indexOf(report.architecture) === -1) {
                  return false;
                }
                if (sk.sharesElement(exclude, report.debugFlags) ||
                    sk.sharesElement(exclude, report.releaseFlags)) {
                  return false;
                }
                if (include.length === 0) {
                  return true;
                }
                if (!sk.sharesElement(include, report.debugFlags) &&
                    !sk.sharesElement(include, report.releaseFlags)) {
                  return false;
                }
                return true;
              });
              line.count = line.reports.length;
              funcCount += line.count;
            });
            func.count = funcCount;
            fileCount += funcCount
          });
          file.count = fileCount;
        });
        return retVal;
      },

      _getURLParams: function(category) {
        return {
          "category": category,
          "file": fuzzer.paramFromPath("file"),
          "func": fuzzer.paramFromPath("func"),
          "line": fuzzer.paramFromPath("line"),
          "name": fuzzer.paramFromPath("name"),
          // TODO(kjlubick) Maybe make this user changeable
          "badOrGrey": "bad",
        };
      },

      _group: function(fuzzes) {
        var files = {};
        // files is a flat array of fuzzes.  We want to turn it into an array
        // of objects like:
        // {
        //   fileName: String,
        //   count: Integer,
        //   byFunction: Array<{
        //     functionName: String,
        //     count: Integer,
        //     byLineNumber: Array<{
        //       lineNumber: Integer,
        //       count: Integer,
        //       reports: Array<Fuzz>
        //     }>
        //   }>
        // }
        // where Fuzz is the original object given to us by the server.  See
        // fuzzer-collapse-details-sk for the Fuzz schema.

        // First we group up the fuzzes by file, func, and line number
        fuzzes.forEach(function(f){
          var file = f.fileName || "UNKNOWN";
          var func = f.functionName || "UNKNOWN";
          var line = f.lineNumber || -1;
          if (!files[file]) {
            files[file] = {};
          }
          if (!files[file][func]) {
            files[file][func] = {};
          }
          if (!files[file][func][line]) {
            files[file][func][line] = [];
          }
          files[file][func][line].push(f)
        });

        // Take the object and put it into arrays, so Polymer can use dom-repeats.
        var fileData = [];
        for (var file in files) {
          var funcs = files[file];
          var byFunction = [];
          for (var func in funcs) {
            var lines = funcs[func];
            var byLineNumber = [];
            for (line in lines) {
              byLineNumber.push({
                count: 0,
                lineNumber: line,
                reports: lines[line],
              });
            }
            byFunction.push({
              count: 0,
              functionName: func,
              byLineNumber: byLineNumber,
            });
          }
          fileData.push({
            count: 0,
            fileName: file,
            byFunction: byFunction,
          })
        }

        return fileData;
      },

      _shouldExpand: function(){
        return fuzzer.paramFromPath("file").length > 0 || fuzzer.paramFromPath("name").length > 0;
      },
    });
  </script>
</dom-module>
