'use strict';

const {app, BrowserWindow} = require('electron');
const ipc = require('electron').ipcMain;
const duplexer = require('duplexer3');
const {spawn} = require('child_process');

var streamIn =  null;
var ffmpeg = null;

function quit(){
  if(streamIn){
    streamIn.end();
    streamIn = null;
  }
  app.quit();
}

ipc.on('close-main-window', function () {
    quit();
});

var lastRenderTime = 0;

var contentBitmap = null;

var duration = 10000;//set duration 10s

var start = Date.now()

ipc.on('to-main-timer', function () {
 /* if(lastMainTimerCalledTime){
    var now = Date.now();
    console.log("time-diff:",now - lastMainTimerCalledTime);
    lastMainTimerCalledTime = now;
  }
  else{
    lastMainTimerCalledTime = Date.now();
  }
*/
  if(contentBitmap && streamIn){
    streamIn.write(contentBitmap);
  }

  if (Date.now() - start >= duration) {
    if (streamIn) {
      streamIn.end();
      streamIn = null;
    }
    if (Date.now() - start >= duration + 10000) {//quit after duration + 10s
      quit();
    }
  }
});

var subarg = require('subarg');

var argv = subarg(process.argv.slice(2));
if (argv.v || argv.version) {
  console.log('electron v' + process.versions.electron);
  console.log('chrome v' + process.versions.chrome);
  return app.quit();
}

if (argv.d) {
  var args = "args: ";
  for (var i in argv) {
    args += i + " = " + argv[i] + "\n";
  }
  console.log(args);
}

if(!argv.u){//url
  console.log("you must input the web url to record with : -u ");
  return app.quit();
}

if(!argv.d){//duration
  console.log("you must set the record duration in seconds with : -d ");
  return app.quit();
}

if(!argv.f){//framerate
  argv.f = "20";
}

if(!argv.w){//width
  argv.w = "800";
}

if(!argv.h){//width
  argv.h = "600";
}

if(!argv.b){//bitrate
  argv.b = "1000k";
}

if(!argv.o){//offscreen
  argv.o = true;
}

function startFFmpeg(videosize) {
  const args = ['-y','-f', 'rawvideo', '-pix_fmt', 'bgra', '-s' ];

  var size = videosize.width + 'x' + videosize.height

  args.push(size);
  args.push('-r');
  args.push(argv.f);
  args.push.apply( args, ['-i', 'pipe:0'] );
   // /*
  args.push('-f');
  args.push('dshow');
  args.push('-i');
  args.push('audio=virtual-audio-capturer');
  //*/
  args.push('-vf')
  args.push('fps=fps='+argv.f)
  args.push('-c:v');
  args.push('libx264');
  args.push('-b:v');
  args.push(argv.b);
  args.push('-r:v');
  args.push(argv.f);

  args.push('-acodec');
  args.push('aac');
  args.push('-shortest');
  args.push(argv._[0]);

  console.log(args.join` `);

  ffmpeg = spawn('ffmpeg', args);
  if (ffmpeg) {
    ffmpeg.stderr.on('data', chunk => console.log(chunk.toString()));
    streamIn = duplexer(ffmpeg.stdin, ffmpeg.stdout);
  }
  else {
    console.log("can't start ffmpeg,please make sure ffmpeg is avaiable");
  }
}

app.disableHardwareAcceleration()

let win
app.once('ready', () => {
  win = new BrowserWindow({
    width:argv.w,
    height:argv.h,
    webPreferences: {
      offscreen: argv.o
    }
  })
  win.loadURL(argv.u)

  var intervalms = 1000 / parseInt(argv.f);
  
  var injectScript = 'const ipcToMain = require("electron").ipcRenderer;function timerToMain (){ ipcToMain.send("to-main-timer");}setInterval(timerToMain,' + intervalms + ');';

  win.webContents.executeJavaScript(injectScript);

  duration = parseInt(argv.d)*1000

  win.webContents.on("paint", function (event, dirty, image) {

    if (!ffmpeg) {
      start = Date.now();
      startFFmpeg(image.getSize());
      if(!ffmpeg){
          sendQuit();
      }
    }
    lastRenderTime = Date.now();
    var elapsed = lastRenderTime - start
    if (elapsed > duration) {
      if (streamIn) {
        streamIn.end();
        streamIn = null;
      }
      console.log("done")
      if(elapsed > duration + 5000){//delay 5s after closingSgit l pipe ,then close
          sendQuit();
      }
    }
    else {
     // streamIn.write(image.getBitmap());
     contentBitmap = image.toBitmap();
    }

    //console.log("painting", elapsed, win.webContents.isOffscreen(), win.webContents.getFrameRate())

  })
  win.webContents.setFrameRate(parseInt(argv.f));
})

function sendQuit(){
  win.webContents.executeJavaScript('require("electron").ipcRenderer.send("close-main-window")');
}