#!/bin/sh
##############################
# name: yt-search
# lisc: gnu gplv3
# main: jadedctrl
# desc: search youtube simply.
##############################

# Usage: yt-search [-csmb] "$search_string"

# --------------------------------------
# a bit of math...

# NUMBER NUMBER --> NUMBER
# Well, subtraction. Y'know...
function subtract {
	local operated=$1
	local operatee=$2
	echo "${1}-${2}" | bc
}



# --------------------------------------
# ... now some string manip...

# NIL --> STRING
# Print an ANSI "unbold" escape string.
function unbold {
	printf "$(tput sgr0)"
}

# STRING --> STRING
# Print an ANSI "bold" escape string.
function bold {
	printf "$(tput bold)"
}

# STRING --> NUMBER
# Return the length of a string
function char_length {
	subtract $(echo $1 | wc -c) 1
}

# STRING NUMBER [STRING] --> STRING
# pad string $1 out to the minimum length $2 with padding $3 (default: "0")
function min_string_length {
	local string="$1"
	local length=$2
	if test -z "$3"; then
		local padding="0"
	else
		local padding="$3"
	fi
	local new="$string"
	if test $(char_length $1) -eq $2; then
		echo $1
	else
		while test $(char_length $new) -lt $2; do
			new="${new}${padding}"
		done
		echo $new
	fi
}

# STRING NUMBER --> STRING
# get the first $2 characters in string $1
function char_get {
	local number=$2
	local string="$1"
	string="$(min_string_length "$string" $number " ")"
	echo "$string" \
	| grep -o "^$(min_string_length "." $number ".")"
}



# --------------------------------------
# ... now for the real deal~!

# STRING --> STRING
# Pass the raw search HTML, get raw video result-lines
function result_lines {
	local search_html="$1"
	echo "$search_html" \
	| grep "<a href=\"\/watch?v=" \
	| grep -v "<span class=\"yt-thumb-simple\"" \
	| grep -v "yt-lockup-playlist-item"
	#| grep -v "<a href=\"/playlist" \
}

# STRING --> STRING 
# Return the video ID of a result_line.
function result_id {
	local result_line="$1"
	echo "$result_line" \
	| sed 's%.*<a href="/watch?v=%%' \
	| sed 's%".*%%'
}

function result_url {
	local result_line="$1"
	local id="$(result_id "$result_line")"
	echo "https://youtube.com/watch?v=${id}"
}

# STRING --> STRING
# Return the title of a result-line.
function result_title {
	local result_line="$1"
	echo "$result_line" \
	| sed 's%.*"  title="%%' \
	| sed 's%".*%%'
}

function result_name {
	local result_line="$1"
	local title="$(result_title "$result_line")"
	echo "$(bold)${title}$(unbold)"
}


# STRING --> STRING
# Return the duration of a result-line.
function result_duration {
	local result_line="$1"
	echo "$result_line" \
	| sed 's%.*> - Duration: %%' \
	| sed 's%\..*%%'
}

# STRING --> STRING
# Return the .yt-lockup-meta-info <ul> of a result-line
function result_meta_ul {
	local result_line="$1"
	echo "$result_line" \
	| sed 's%.*<ul class="yt-lockup-meta-info">%%' \
	| sed 's%</ul>.*%%'
}

# STRING --> STRING
# Return the "Uploaded..." string of a result-line
function result_uploaded {
	local result_line="$1"
	local result_meta_ul="$(result_meta_ul "$result_line")"
	echo "$result_meta_ul" \
	| sed 's%<li>%%' \
	| sed 's% ago</li>.*%%'
}

# STRING --> NUMBER
# Return the view-count of a result-line
function result_views {
	local result_line="$1"
	local result_meta_ul="$(result_meta_ul "$result_line")"
	echo "$result_meta_ul" \
	| sed 's%.*<li>%%g' \
	| sed 's% views</li>.*%%' \
	| sed 's%,%%g'
}

# STRING --> STRING
# Format a result-line into a mediumly-pretty, one-line string~
function result_format_compact {
	local result_line="$1"
	local title="$(char_get "$(result_name "$result_line")" 40)$(unbold)"
	local id="$(result_id "$result_line")"

	echo "$name | $id"
}

# STRING --> STRING
# Format a result-line into a mediumly-pretty, one-line string~
function result_format_small {
	local result_line="$1"
	local name="$(char_get "$(result_name "$result_line")" 40)$(unbold)"
	local url="$(result_url "$result_line")"

	echo "$name | $url"
}

# STRING --> STRING
# Format a result-line into a mediumly-pretty, one-line string~
function result_format_medium {
	local result_line="$1"
	local name="$(char_get "$(result_name "$result_line")" 40)$(unbold)"
	local duration="$(result_duration "$result_line")"
	local url="$(result_url "$result_line")"

	echo "$name | $duration | $url"
}

# STRING --> STRING
# Format a result-line into a pretty string~
function result_format_big {
	local result_line="$1"
	local name="$(char_get "$(result_name "$result_line")" 79)$(unbold)"
	local duration="$(result_duration "$result_line")"
	local uploaded="$(result_uploaded "$result_line")"
	local views="$(result_views "$result_line")"
	local url="$(result_url "$result_line")"

	echo "$name"
	echo "$duration |  $uploaded |  $views  |  $url"
}



# --------------------------------------
# invocation <3

function usage {
	echo "usage: yt-search [-csmb] query"
	exit 2
}

# --------------------------------------

if test -z "$1"; then
	usage
elif test -n "$2"; then
	QUERY="$2"
	case "$1" in
		"-c") FORMAT="compact" ;;
		"-s") FORMAT="small" ;;
		"-m") FORMAT="medium" ;;
		"-b") FORMAT="big" ;;
	esac
else
	QUERY="$1"
	FORMAT="big"
fi

# --------------------------------------

QUERY="$(echo "$QUERY" | sed 's/ /+/g')"
search_html="$(gendl "https://youtube.com/results?search_query=$QUERY")"
result_lines="$(result_lines "$search_html")" 

IFS='
'

for result in $result_lines; do
	case "$FORMAT" in
		"compact") result_format_compact "$result" ;;
		"small") result_format_small "$result" ;;
		"medium") result_format_medium "$result" ;;
		"big") result_format_big "$result" ;;
	esac
done