text: /**
   * Log requests for build HAR output
   *
   * Depends on windowPerformance module!
   */
  "use strict";
  
  var fs = require("fs");
  
  /**
   * Inspired by phantomHAR
   * @author: Christopher Van (@cvan)
   * @homepage: https://github.com/cvan/phantomHAR
   * @original: https://github.com/cvan/phantomHAR/blob/master/phantomhar.js
   */
  
  function createHAR(page, creator) {
    // @see: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
    var address = page.address;
    var title = page.title;
    var startTime = page.startTime;
    var resources = page.resources;
  
    var entries = [];
  
    resources.forEach(function (resource) {
      var request = resource.request;
      var response = resource.response;
  
      if (!request || !response) {
        return;
      }
  
      // Exclude data URIs from the HAR because they aren't
      // included in the spec.
      if (request.url.substring(0, 5).toLowerCase() === "data:") {
        return;
      }
  
      entries.push({
        cache: {},
        pageref: address,
        request: {
          // Accurate bodySize blocked on https://github.com/ariya/phantomjs/pull/11484
          bodySize: -1,
          cookies: [],
          headers: request.headers,
          // Accurate headersSize blocked on https://github.com/ariya/phantomjs/pull/11484
          headersSize: -1,
          httpVersion: "HTTP/1.1",
          method: request.method,
          queryString: [],
          url: request.url,
        },
        response: {
          bodySize: response.bodySize,
          cookies: [],
          headers: response.headers,
          headersSize: response.headersSize,
          httpVersion: "HTTP/1.1",
          redirectURL: "",
          status: response.status,
          statusText: response.statusText,
          content: {
            mimeType: response.contentType || "",
            size: response.bodySize, // uncompressed
            text: "",
          },
        },
        startedDateTime: resource.startTime && resource.startTime.toISOString(),
        time: response.timeToLastByte,
        timings: {
          blocked: 0,
          dns: -1,
          connect: -1,
          send: 0,
          wait: 0, // response.timeToFirstByte || 0,
          receive: 0, // response.receiveTime,
          ssl: -1,
        },
      });
    });
  
    return {
      log: {
        creator: creator,
        entries: entries,
        pages: [
          {
            startedDateTime: startTime.toISOString(),
            id: address,
            title: title,
            pageTimings: {
              onLoad: page.onLoad || -1,
              onContentLoad: page.onContentLoad || -1,
            },
          },
        ],
        version: "1.2",
      },
    };
  }
  /** End **/
  
  module.exports = function (phantomas) {
    var param = phantomas.getParam("har"),
      path = "",
      timeToLastByte;
  
    if (param === false) {
      return;
    }
  
    var page = {
      origin: undefined,
      resources: [],
      title: undefined,
      address: undefined,
      startTime: undefined,
      endTime: undefined,
      onDOMReadyTime: undefined,
      windowOnLoadTime: undefined,
      timeToLastByte: undefined,
      onLoad: undefined,
      onContentLoad: undefined,
    };
  
    var creator = {
      name: "Phantomas - (using phantomHAR)",
      version: phantomas.getVersion(),
    };
  
    if (typeof param === "undefined") {
      phantomas.log("HAR: no path specified, use --har <path>");
      return;
    }
  
    // --har
    if (param === true) {
      // defaults to "phantomas_2013-12-07T20:15:01.521Z.har"
      path = "phantomas_" + new Date().toJSON() + ".har";
    }
    // --har [file name]
    else {
      path = param;
    }
  
    phantomas.log("Will be stored in %s", path);
  
    phantomas.on("pageBeforeOpen", function (p) {
      page.origin = p;
    });
  
    phantomas.on("loadFinished", function () {
      page.endTime = new Date();
    });
  
    phantomas.on("send", (entry) => {
      const resId = entry._requestId;
  
      page.resources[resId] = {
        id: resId,
        request: entry,
        response: null,
        startTime: new Date(),
      };
  
      // a first request has been made?
      if (typeof page.startTime === "undefined") {
        page.startTime = new Date();
      }
    });
  
    phantomas.on("recv", (entry) => {
      const resId = entry.id;
  
      page.resources[resId].response = entry;
      timeToLastByte = entry.timeToLastByte;
    });
  
    phantomas.on("metric", function (name, value) {
      switch (name) {
        case "domContentLoaded":
          page.onDOMReadyTime = value;
          break;
        case "domComplete":
          page.windowOnLoadTime = value;
          break;
        case "timeToLastByte":
          page.timeToLastByte = value;
          break;
      }
    });
  
    phantomas.on("report", () => {
      // make resources list a real array
      page.resources = Object.values(page.resources);
  
      // Set endTime if page was not finished correctly
      if (!page.endTime) page.endTime = new Date();
  
      // If metric 'windowOnLoadTime' hasn't been fired, compute it
      //if (!page.windowOnLoadTime)
      //	page.windowOnLoadTime = page.endTime.getTime() - page.startTime.getTime();
  
      // If metric 'timeToLastByte' hasn't been fired, use last entry
      if (!page.timeToLastByte) page.timeToLastByte = timeToLastByte;
  
      //page.address = page.origin.url;
      //page.title = page.origin.title;
  
      // Times (windowOnLoadTime, onDOMReadyTime) are relative to responseEnd entry
      // in NavigationTiming (represented by timeToLastByte metric)
      page.onLoad = page.timeToLastByte + page.windowOnLoadTime;
      page.onContentLoad = page.timeToLastByte + page.onDOMReadyTime;
  
      phantomas.log('Generating for <%s> ("%s")', page.address, page.title);
      phantomas.log("Page data: %j", page);
  
      var har, dump;
  
      try {
        har = createHAR(page, creator);
      } catch (e) {
        console.error(e);
        phantomas.log("Failed to build - %s", e);
        return;
      }
  
      phantomas.log("Result: %j", har);
  
      try {
        dump = JSON.stringify(har);
      } catch (e) {
        console.error(e);
        phantomas.log("Failed to stringify HAR to JSON - %s!", e);
        return;
      }
  
      phantomas.log("Saving to %s ...", path);
      try {
        // https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options
        fs.writeFileSync(path, dump);
      } catch (e) {
        console.error(e);
        phantomas.log("Failed to save HAR - %s!", e);
        return;
      }
  
      // let clients know that we save a HAR file
      phantomas.emit("har", path);
      phantomas.log("Done");
    });
  };
  