#!/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 $(find /lib/modules/ -name "*.ko"); 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})" &
}
