#!/bin/bash

query="$*"
browser="/usr/bin/linkhandler"
search_dir="$HOME/scripts/search"
ivserver=""

if [ -z "$query" ]; then
    echo "what are you looking for? bc no input"
    echo "example: ./search mass of sun"
    exit 1
fi

if [ "$(echo "$query" | tr -d ' ' | wc -m)" -lt 3 ]; then
    echo "input too short"
    echo "example: ./search mass of sun"
    exit 1
fi



engines=("startpage" "ddg" "wiby" "yandex" "brave" "ghostery")


output="/tmp/searches.json"


make_filename() {
    local q="$1"
    local base

    base=$(printf '%s' "$q" \
        | iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null \
        | tr '[:upper:]' '[:lower:]' \
        | sed 's/[^a-z0-9]\+/_/g; s/^_//; s/_$//')

    [ -z "$base" ] && base="search"
    echo "${base}.json"
}


init_json() {
    local ts
    ts=$(date --iso-8601=seconds)

    if [ ! -f "$output" ] || [ ! -s "$output" ]; then
        jq -n --arg q "$query" --arg ts "$ts" \
            '{meta:{query:$q,timestamp:$ts}, web:[]}' > "$output"
        return
    fi

    # if mess then...
    if ! jq -e 'has("web") and (.web | type=="array") and has("meta")' "$output" >/dev/null 2>&1; then
        jq -n --arg q "$query" --arg ts "$ts" \
            '{meta:{query:$q,timestamp:$ts}, web:[]}' > "$output"
    fi
}

add_result() {
    local result="$1"
    local url_item

    url_item=$(echo "$result" | jq -r '.url')
    [ -z "$url_item" ] && return

	# again? +1
    if jq -e --arg url "$url_item" '.web[] | select(.url == $url)' "$output" >/dev/null 2>&1; then
        jq --arg url "$url_item" '
          .web = (.web | map(
            if .url == $url then .points += 1 else . end
          ))
        ' "$output" > /tmp/searches.tmp && mv /tmp/searches.tmp "$output"
    else
        # new
        jq --argjson result "$result" '
          .web += [$result]
        ' "$output" > /tmp/searches.tmp && mv /tmp/searches.tmp "$output"
    fi
}


adjust_points() {
    jq '
      .web |= map(
        .points +=
          (if (.url | test("\\.pl([/?#]|$)"))      then 1  else 0 end) +
          (if (.url | test("reddit\\.com"))        then 1  else 0 end) +
          (if (.url | test("facebook\\.com"))      then -1 else 0 end)
      )
    ' "$output" > /tmp/searches.tmp && mv /tmp/searches.tmp "$output"
}



encode_query() {
    printf '%s' "$1" | jq -sRr @uri
}

# Marginalia
get_results_marginalia() {
    local query="$1"
    local enc_query
    enc_query=$(printf '%s' "$query" | jq -sRr @uri)
    local url="https://api.marginalia.nu/public/search/$enc_query"

    echo "calling marginalia: $url"

    local response
    response=$(curl -s "$url")

    if ! echo "$response" | jq empty >/dev/null 2>&1; then
        echo "marginalia json error"
        return
    fi

    local results
    results=$(echo "$response" | jq -c '(.results // [])[] | {title, url, description, points: 1}')

    [ -z "$results" ] && return

    while IFS= read -r result; do
        [ -z "$result" ] && continue
        add_result "$result"
    done <<< "$results"
}

# 4get
get_results() {
    engine=$1
    query=$2
    encoded_query=$(encode_query "$query")
    url="https://$ivserver/api/v1/web?s=$encoded_query&scraper=$engine&nsfw=yes"

    echo "calling $url"

    response=$(curl -s "$url")

    #  JSON good?
    if ! echo "$response" | jq empty >/dev/null 2>&1; then
        echo "wrong JSON in $engine API"
        return
    fi

    # status ok?
    if ! echo "$response" | jq -re '.status == "ok"' >/dev/null 2>&1; then
        echo "API status != ok dla $engine"
        return
    fi

    results=$(echo "$response" | jq -c '(.web // [])[] | {title, url, description, points: 1}')

    [ -z "$results" ] && return

    while IFS= read -r result; do
        [ -z "$result" ] && continue
        add_result "$result"
    done <<< "$results"
}



mkdir -p "$search_dir"
fname=$(make_filename "$query")

skip_json=0

if [ -f "$search_dir/$fname" ]; then
    echo "'$query' already exists: $search_dir/$fname"
    skip_json=1
fi


if [ $skip_json -eq 0 ]; then
init_json

for engine in "${engines[@]}"; do
    echo "$engine brrr..."
    get_results "$engine" "$query"
    sleep 5
done

echo "marginalia brrr"
get_results_marginalia "$query"


adjust_points

jq '.web |= (sort_by(.points) | reverse)' "$output" > /tmp/searches.tmp && mv /tmp/searches.tmp "$output"


mkdir -p "$search_dir"
fname=$(make_filename "$query")
cp "$output" "$search_dir/$fname"

echo "results in $output"
echo "saved - $search_dir/$fname"
fi

input_file="$search_dir/$fname"
output_file="$search_dir/${fname%.json}.html"






if [ -f "$output_file" ]; then
    echo "$output_file already exists"
    exit 0
fi


if ! jq empty "$input_file" >/dev/null 2>&1; then
    echo "$input_file error"
    exit 1
fi


query=$(jq -r '.meta.query // ""' "$input_file")

bold_query() {
    local q="$1"
    perl -e '
        my $q = shift;
        my $text = do { local $/; <STDIN> };
        my @w = grep { length } split /\s+/, $q;
        for my $w (@w) {
            $text =~ s/\b\Q$w\E\b/<span class="bolded_query">$&<\/span>/ig;
        }
        print $text;
    ' "$q"
}


{
echo '<!doctype html>'
echo '<html lang="en">'
echo '<head>'
echo '  <meta charset="utf-8">'
echo "  <title>search - $query</title>"
echo '  <style>
    body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 3em 2em 4em 4em;
        box-sizing: border-box;
    }

    .bolded_query {
        font-weight: bold;
    }

#query {
    font-size: 1.5em;
    color: black;
    background: yellow;
    border-bottom: 1px solid black;
    margin-bottom: 0.5em;
    display: inline-block;
    padding: 0.2em 0.4em;
}


    h3 {
        font-size: 16px;
        font-weight: normal;
        margin: 0;
        padding: 0;
    }

    .r {
        margin: 0;
    }

    .b {
        font-weight: bold;
    }

    a:link {
        color: #11c;
    }

    a.fl {
        color: #4272db;
        text-decoration: none;
    }

    .flc a {
        color: #4272db;
        text-decoration: none;
    }

    cite {
        color: #0E774A;
        font-style: normal;
    }

    li.g {
        font-size: 13px;
        margin-bottom: 14px;
        margin-top: 0;
    }

    h1, ol, ul {
        margin: 0;
        padding: 0;
    }

    ol li {
        list-style: none;
    }

    .s br {
        display: none;
    }

    a:hover {
        text-decoration: underline;
    }
  </style>'
echo '</head>'
echo '<body>'
} > "$output_file"


printf '  <div id="query">%s</div>\n' "$query" >> "$output_file"

echo '  <ol>' >> "$output_file"

# json to html

jq -c '.web[] | {url, title, description}' "$input_file" |
while IFS= read -r item; do
    url=$(printf '%s' "$item" | jq -r '.url')
    title=$(printf '%s' "$item" | jq -r '.title')
    desc=$(printf '%s' "$item" | jq -r '.description')

    
    title=$(printf '%s' "$title" | bold_query "$query")
    desc=$(printf '%s' "$desc" | bold_query "$query")

    {
        echo '    <li class="g">'
        echo '        <h3 class="r">'
        printf '            <a href="%s">%s</a>\n' "$url" "$title"
        echo '        </h3>'
        echo '        <div class="s">'
        printf '            %s\n' "$desc"
        echo '            <div>'
        printf '                <cite>%s</cite>\n' "$url"
        echo '            </div>'
        echo '        </div>'
        echo '    </li>'
    } >> "$output_file"
done


{
echo '  </ol>'
echo '</body>'
echo '</html>'
} >> "$output_file"

echo "HTML saved as $output_file"

rm -f "$output"

$browser $output_file
