#!/bin/sh

# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Check uber shopfloor server, fetch and parse board config.
#
# Channel image URLs and checksums are sent out through stdout for shell
# to eval. The format:
#
#   SRC_{CHANNEL}_URL=http://shopfloor_server:port/pathto/gzimage
#   SRC_{CHANNEL}_CHECKSUM=plain_image_binarysha1_base64
#
# For memento updater compatibility, images should be generated by script
# make_factory_package.sh.
#
# Example:
#   SHOPFLOOR="http://SF_SERVER:SF_PORT"
#   BOARD="testboard"
#   result=$(ping_shopfloor)
#   rc="$?"
#   if [ "$rc" = "0" ]; then
#     eval "$result"
#   fi
#   if [ "$SHOPFLOOR_INSTALL" = "1" ]; then
#     do_install
#     ...
#

sf_log() {
  echo "$(date) $*" >&2
}

ping_shopfloor() {
  local channel_hash=""
  local channel_file=""
  local channel_name=""
  local config_file="default.conf"
  local line=""
  local resource_url=""
  local wget_output=""
  local wget_rc="0"
  local channels=""
  local cleanup_files=""

  # Get config file name from BOARD
  if [ -n "$BOARD" ]; then
    config_file="${BOARD}.conf"
  fi

  # Get resource URL from SHOPFLOOR or OMAHA
  if [ -n "$SHOPFLOOR" ]; then
    resource_url="$SHOPFLOOR/res"
  elif [ -n "$OMAHA" ]; then
    resource_url="${OMAHA%/update}/res"
  else
    sf_log "ping_shopfloor: SHOPFLOOR and OMAHA not found."
    return 1
  fi

  # Try to get resource map from Umpire. ETH_INTERFACE is passed from
  # factory_install.sh.
  local sn="$(vpd -i RO_VPD -g serial_number)" || sn=""
  local mlb_sn="$(vpd -i RO_VPD -g mlb_serial_number)" || mlb_sn=""
  local board="${BOARD}"
  local mac_addr="$(ip link show ${ETH_INTERFACE} | grep link/ether |
      tr -s ' '| cut -d ' ' -f 3)"
  local resourcemap_rc="0"
  local resourcemap=""
  local mac="mac.${ETH_INTERFACE}=${mac_addr};"
  local values="sn=${sn}; mlb_sn=${mlb_sn}; board=${board}; ${mac}"
  local empty_values="firmware=; ec=; stage=;"
  local x_umpire_dut_header="X-Umpire-DUT: ${values} ${empty_values}"
  local target="${resource_url%/res}/resourcemap"
  sf_log "ping_shopfloor: ${x_umpire_dut_header}"

  resourcemap="$(wget -O - --header "${x_umpire_dut_header}" "${target}")" ||
      resourcemap_rc="$?"

  if [ "$resourcemap_rc" != "0" ]; then
    sf_log "ping_shopfloor: could not fetch resourcemap."
  else
    sf_log "ping_shopfloor: got resourcemap: ${resourcemap}"
    config_file="$(echo "${resourcemap}" | grep download_conf |
        cut -d ':' -f 2 | tr -d ' ')"
    sf_log "ping_shopfloor: config_file: ${config_file}"
  fi

  # Ping shopfloor by fetching the config file
  wget_output="$(mktemp "/tmp/conf_XXXXXXXX")"
  cleanup_files="$wget_output"
  wget -O $wget_output "$resource_url/$config_file" 2>/dev/null ||
    wget_rc="$?"

  if [ "$wget_rc" != "0" ]; then
    sf_log "ping_shopfloor: could not fetch $resource_url/$config_file"
    [ -f "$cleanup_files" ] && rm $cleanup_files
    return 1
  fi

  # Fix shell read line without \n
  echo >>"$wget_output"

  # Parse channels and skip comments in a subprocess
  channels="$(mktemp "/tmp/sf_XXXXXXXX")"
  cleanup_files="$cleanup_files $channels"
  while IFS= read line; do
    # Remove leading whitespaces
    line=$(echo $line | sed -e 's/^[ \t]*//')
    # Skip comment and empty lines
    [ -n "$(echo $line | grep -E '^#')" -o -z "$line" ] && continue
    # Split channel, file, and hash
    channel_name=$(echo $line | cut -d':' -f1)
    channel_file=$(echo $line | cut -d':' -f2)
    channel_hash=$(echo $line | cut -d':' -f3)
    if [ -z "$channel_name" -o -z "$channel_file" -o -z "$channel_hash" ]; then
      sf_log "ping_shopfloor: not a channel $resource_url/$config_file ($line)"
      [ -n "$cleanup_files" ] && rm $cleanup_files
      return 1
    fi
    echo "SRC_${channel_name}_URL=$resource_url/$channel_file" >> "$channels"
    echo "SRC_${channel_name}_CHECKSUM=$channel_hash" >> "$channels"
  done <"$wget_output"

  if [ "$?" != "0" ]; then
    [ -n "$cleanup_files" ] && rm $cleanup_files
    return 1
  fi

  cat "$channels"
  echo "SHOPFLOOR_INSTALL=1"

  [ -n "$cleanup_files" ] && rm $cleanup_files
  return 0
}

# Bring up network
bringup_network() {
  # Probe USB Ethernet devices.
  local module
  local module_name
  local result=1
  for module in /lib/modules/*/kernel/drivers/net/usb/*; do
    module_name="$(basename "${module%.ko}")"
    modprobe ${module_name}
  done

  # Try to bring up network and get an IP address on each Ethernet device.
  for iface in $(ifconfig -a | grep -Eo 'eth[0-9]+'); do
    ifconfig ${iface} up || true
    udhcpc -t 3 -f -q -n -i ${iface} -s /etc/udhcpc.script && result=0
  done
  return ${result}
}

# Try to register into Overlord server if available.
register_to_overlord() {
  local omaha_url="$1"
  local tty_file="$2"
  local log_file="$3"
  local machine_id=""

  local server="${omaha_url#*://}"
  server="${server%%:*}"
  server="${server%% }"
  server="${server## }"
  [ -n "${server}" ] || return 1

  # Build machine ID by MAC addresses.
  local eth="$(netstat -r | grep '^default ')"
  machine_id="$(ip link show ${eth##* } | grep 'link/ether' |
                sed 's/.*ether //;s/ brd .*//' | tr '\n' ',' | sed 's/,$//')"
  [ -n "${machine_id}" ] || machine_id="UnknownMachineId.$(uuidgen 2>/dev/null)"

  local header_tty="$(mktemp)" header_log="$(mktemp)"
  local header='{"name":"register",
                 "params":{"sid":"%s","mid":"%s","format":%s,"mode":4}}\r\n'
  printf "${header}" "Console" "${machine_id}" "1" >"${header_tty}"
  printf "${header}" "DebugLog" "${machine_id}" "0" >"${header_log}"

  # nc@busybox may have problem in receiving data from pipe (due to buffer size
  # and timeout), so we should write the command into a scripting file and let
  # busybox create the pipe internally.
  local tty_piper="$(mktemp)" log_piper="$(mktemp)"
  echo "tail -n +0 -qF ${header_tty} ${tty_file}" >"${tty_piper}"
  echo "tail -n +0 -qF ${header_log} ${log_file}" >"${log_piper}"
  chmod a+rx "${tty_piper}" "${log_piper}"
  local connect_cmd="while true; do busybox nc ${server} 4455 -e %s;
                     sleep 10; done"

  if [ -n "${tty_file}" ]; then
    setsid sh -c "$(printf "${connect_cmd}" ${tty_piper})" &
  fi
  setsid sh -c "$(printf "${connect_cmd}" ${log_piper})" &
}
