import os
import subprocess

from flask import Flask, request, jsonify, abort
import google.cloud
from google.cloud import storage

app = Flask(__name__)


def record(filename, duration):
    """Record screen to |filename| and return error message if ffmpeg fails."""
    video_device = '/dev/video0'

    # Check if the video device exists.
    cmd = 'ls {0}'.format(video_device)
    proc = None
    try:
        proc = subprocess.check_output(cmd.split())
    except subprocess.CalledProcessError:
        abort(500, 'Seems like the video device was not found.')

    # Check if the video device is already in use and kill if so.
    cmd = 'lsof -t {0}'.format(video_device)
    proc = None
    try:
        proc = subprocess.check_output(cmd.split())
    except subprocess.CalledProcessError:
        abort(500, 'No process must\'ve been found. That\'s okay.')
    if proc is not None:
        kill_cmd = 'kill -9 {0}'.format(proc)
        proc = subprocess.call(kill_cmd.split())

    # Reset some modules for safety:
    # TODO(vsuley): This is hacky: fix the underlying problem.
    # crbug.com/970936
    r1 = subprocess.call(['modprobe', '-vr', 'uvcvideo'])
    r2 = subprocess.call(['modprobe', '-v', 'uvcvideo'])
    if r1 != 0 or r2 != 0:
        return 'error reinstalling uvcvideo module'

    ffmpeg_path = '/root/bin/ffmpeg'
    ffmpeg = [ffmpeg_path, '-f', 'video4linux2', '-s', '1920x1080', '-r', '60',
              '-i', '/dev/video0', '-f', 'alsa', '-i', 'hw:1', '-qscale', '2',
              '-t', duration, '-strict', 'experimental', '-acodec', 'aac',
              '-vcodec', 'libx264', '-pix_fmt', 'yuv420p', '-loglevel',
              'error', '-y', filename]

    # TODO(vsuley): Is 10s too much? Figure out how small you can make
    # this number without breaking stuff. crbug.com/970938
    wait_time = int(duration) + 10
    try:
        subprocess.check_output(ffmpeg, stderr=subprocess.STDOUT,
                                timeout=wait_time)
        return None
    except subprocess.CalledProcessError as e:
        return e.output.decode('utf-8')
    except subprocess.TimeoutExpired as e:
        return 'ffmpeg command timed out after %s seconds' % wait_time


def upload(filename):
    """Upload the recorded video file to Storage."""
    BUCKET_NAME = 'cros-av-analysis'
    try:
        client = storage.Client()
        bucket = client.get_bucket(BUCKET_NAME)
        blob = bucket.blob(filename)

        blob.upload_from_filename(filename)
        blob.make_public()
    except google.cloud.exceptions as e:
        return 'Storage error: %s' % e

    return None


def outcome(status, filename):
    """Clean up generated video and return status as JSON."""
    try:
        os.remove(filename)
    except OSError as e:
        app.logger.info(e)

    if status['error'] is None:
        del status['error']

    return jsonify(status)


@app.errorhandler(500)
def log_and_abort(message):
    """Logs the error message and also return message"""
    app.logger.error(message)
    return message


@app.route('/record_and_upload', methods=['POST'])
def record_and_upload():
    """
    Call ffmpeg to record screen then upload results to Storage.

    @params filename (required): Filename to give recording.
    @params duration (required): Length in seconds to record.

    @returns: JSON containing error status.

    """
    app.logger.info('Args receieved: ' + str(request.args))
    filename = request.args.get('filename')
    duration = request.args.get('duration')
    post_data = str(request.data.decode('utf-8'))
    app.logger.info('The form data is: ' + str(post_data))
    status = {}

    if not filename or not duration:
        status['error'] = 'filename and duration are required'
        return jsonify(status), 400

    app.logger.info('Starting recording')
    rec_error = record(filename, duration)

    # Short circuit if ffmpeg failed.
    if rec_error is not None:
        abort(500, rec_error)

    app.logger.info('Starting upload')
    status['error'] = upload(filename)
    return outcome(status, filename)
