#!/bin/bash
# Desc: Searches for erotic phrases in text files in specified working directory
# Usage: find_erotica.sh [dir]
# Depends: GNU Find utils, GNU Parallel 20210822, GNU Grep, GNU Coreutils 8.32, bc
# Version: 0.3.0


FIN_MAX=400;
export SHOW_FILENAME=false;
export CONTEXT_NOUN=128;
export CONTEXT_ADJ=64;
export CONTEXT_VERB=32;
export CONTEXT_MIX_1=32
export CONTEXT_MIX_2=32
export CONTEXT_PHRASE=16;


yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status
must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails
search_thread() {
    # Desc: Apply filters to a file
    # Depends: find_nouns();
    # Input:  arg1    file path
    # Output: stdout  search results

    if [[ ! -f "$1" ]]; then die "FATAL:Not a file:$1"; fi;
    local fin="$1";
    # yell "STATUS:Starting search_thread() on ${fin}"  # debug;
    # yell "Processing: ${fin}..."; # debug

    mapfile -t output < <(
        find_nouns "$1" | \
            find_adjectives | \
            find_verbs | \
#           find_mix_1 | \
#           find_mix_2 | \
            find_phrase | \
            grep -v -- '-$'; # ADJUST ME
    );

    if [[ "${#output[@]}" -gt 1 ]]; then
        printf "%s\n" "$(basename "${fin}" )";
        printf "Result: %d lines.\n" "${#output[@]}";
        printf "%s\n" "${output[@]}";
        printf "\n";
    fi;

    # yell "STATUS:Finished search_thread() on ${fin}"  # debug;
};
find_nouns() {
    # Desc: Find nouns
    # Usage: find_nouns [path]
    # Input:  arg1          text file path
    #         CONTEXT_NOUN  grep parameter
    # Output: stdout  lines matching grep patterns

    if [[ ! -f "$1" ]]; then die "FATAL:Not a file:$1"; fi;
    fin="$1";

    #yell "STATUS:Starting find_nouns() on $fin"  # debug;

    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--extended-regexp');
    if [[ "$SHOW_FILENAME" == "true" ]]; then cmd+=('--with-filename'); fi;
    cmd+=('--line-number');
    cmd+=('--context' "$CONTEXT_NOUN");
    cmd+=('-e' 'nipple');
    cmd+=('-e' 'areola');
    cmd+=('-e' 'breast');
    cmd+=('-e' 'vulva');
    cmd+=('-e' 'womanhood');
    cmd+=('-e' 'manhood');
    cmd+=('-e' 'his member');
    cmd+=('-e' 'slit');
    cmd+=('-e' 'pussy');
    cmd+=('-e' 'vagina');
    cmd+=('-e' ' cock');
    cmd+=('-e' 'dildo');
    cmd+=('-e' 'shaft');
    cmd+=('-e' 'blood');
    cmd+=('-e' ' lust');
    cmd+=('-e' 'tongue');
    cmd+=('-e' 'neck');
    cmd+=('-e' 'voyeur');
    cmd+=('-e' 'ecstacy');
    cmd+=('-e' 'pleasure');
    cmd+=('-e' 'tingle');
    cmd+=('-e' 'orgasm');
    cmd+=('-e' 'lips');
    cmd+=('-e' 'lovers');
    cmd+=('-e' 'hard-on');
    cmd+=('-e' 'sex');
    cmd+=('-e' 'throat');
    cmd+=('-e' 'cleavage');
    cmd+=('-e' 'kiss');
    cmd+=('--');
    cmd+=("$fin");
    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
    #printf "Found %d matching lines for nouns.\n" "${#output[@]}" 1>&2; # debug
    # yell "STATUS:Finished find_nouns() on $fin"  # debug;
}; # find nouns
find_adjectives() {
    # Desc: Find adjectives
    # Usage: cat *.txt | find_adjectives
    # Input:  stdin        input lines
    #         CONTEXT_ADJ  grep parameter
    # Output: stdout  lines matching grep patterns

    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--extended-regexp');
    cmd+=('--context' "$CONTEXT_ADJ");
    cmd+=('-e' 'handsome');
    cmd+=('-e' 'gorgeous');
    cmd+=('-e' 'beautiful');
    cmd+=('-e' 'bewitching');
    cmd+=('-e' 'seductive');
    cmd+=('-e' 'lusty');
    cmd+=('-e' 'comely');
    cmd+=('-e' 'stunning');
    cmd+=('-e' 'elegant');
    cmd+=('-e' 'exquisite');
    cmd+=('-e' 'luxurious');
    cmd+=('-e' 'ravishing');
    cmd+=('-e' 'magnificent');
    cmd+=('-e' 'glistening');
    cmd+=('-e' 'lovely');
    cmd+=('-e' 'loving');
    cmd+=('-e' 'sexy|sexual|sexiest');
    cmd+=('-e' 'sweet');
    cmd+=('-e' 'sensual');
    cmd+=('-e' 'arousing');
    cmd+=('-e' 'warm');
    cmd+=('-e' 'moist');
    cmd+=('-e' 'soaked');
    cmd+=('-e' 'hot');
    cmd+=('-e' 'gentle');
    cmd+=('-e' 'supple');
    cmd+=('-e' 'tender');
    cmd+=('-e' 'pleasurabl');
    cmd+=('-e' 'buxom|busty|curvy');
    cmd+=('-e' 'naked|nude');
    cmd+=('--');
    cmd+=('-');

    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
    #printf "Found %d matching lines for adjectives.\n" "${#output[@]}" 1>&2; # debug
}; # find adjectives
find_verbs() {
    # Desc: Find verbs
    # Usage: cat *.txt | find_verbs
    # Input:  stdin         input lines
    #         CONTEXT_VERB  grep parameter
    # Output: stdout  lines matching grep patterns

    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--extended-regexp');
    cmd+=('--context' "$CONTEXT_VERB");
    cmd+=('-e' 'love');
    cmd+=('-e' 'nuzzle');
    cmd+=('-e' 'pleasure');
    cmd+=('-e' 'make love');
    cmd+=('-e' 'fuck');
    cmd+=('-e' 'arouse');
    cmd+=('-e' 'quiver');
    cmd+=('-e' 'tremble');
    cmd+=('-e' 'caress');
    cmd+=('-e' 'knead');
    cmd+=('-e' 'kiss');
    cmd+=('-e' 'moan');
    cmd+=('-e' 'suck|suckle');
    cmd+=('-e' 'fondle');
    cmd+=('-e' 'grope');
    cmd+=('-e' 'feel up|felt up|felt (me|her|him) up');
    cmd+=('--');
    cmd+=('-');
    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
    #printf "Found %d matching lines for verbs.\n" "${#output[@]}" 1>&2; # debug
}; # find verbs
find_mix_1() {
    # Desc: Filter mix 1
    # Usage: cat *.txt | find_mix_1
    # Input:  stdin         input lines
    #         CONTEXT_VERB  grep parameter
    # Output: stdout  lines matching grep patterns
    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--context' "$CONTEXT_MIX_1");
    cmd+=('-e' 'kiss');
    cmd+=('-e' 'breast');
    cmd+=('-e' 'tits');
    cmd+=('-e' 'manhood');
    cmd+=('-e' 'vagina');
    cmd+=('-e' 'sex');
    cmd+=('--');
    cmd+=('-');
    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
};
find_mix_2() {
    # Desc: Filter mix 2
    # Usage: cat *.txt | find_mix_2
    # Input:  stdin         input lines
    #         CONTEXT_VERB  grep parameter
    # Output: stdout  lines matching grep patterns

    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--context' "$CONTEXT_MIX_2");
    cmd+=('-e' 'nipple');
    cmd+=('-e' 'womanhood');
    cmd+=('-e' 'manhood');
    cmd+=('-e' 'slit');
    cmd+=('-e' 'pussy');
    cmd+=('-e' 'vagina');
    cmd+=('-e' 'cock');
    cmd+=('-e' 'shaft');
    cmd+=('-e' '\ lust');
    cmd+=('-e' 'voyeur');
    cmd+=('-e' 'ecstacy');
    cmd+=('-e' 'tingle');
    cmd+=('-e' 'orgasm');
    cmd+=('-e' 'gorgeous');
    cmd+=('-e' 'bewitching');
    cmd+=('-e' 'seductive');
    cmd+=('-e' 'lusty');
    cmd+=('-e' 'stunning');
    cmd+=('-e' 'ravishing');
    cmd+=('-e' 'lovely');
    cmd+=('-e' 'sexy');
    cmd+=('-e' 'sweet');
    cmd+=('-e' 'sexiest');
    cmd+=('-e' 'sensual');
    cmd+=('-e' 'arousing');
    cmd+=('-e' 'moist');
    cmd+=('-e' 'love');
    cmd+=('-e' 'nuzzle');
    cmd+=('-e' 'pleasure');
    cmd+=('-e' 'make\ love');
    cmd+=('-e' 'sex');
    cmd+=('-e' 'fuck');
    cmd+=('-e' 'arouse');
    cmd+=('-e' 'kiss');
    cmd+=('-e' 'breast');
    cmd+=('-e' 'tits');
    cmd+=('-e' 'manhood');
    cmd+=('-e' 'vagina');
    cmd+=('-e' 'lips');
    cmd+=('-e' 'lovers');
    cmd+=('--');
    cmd+=('-');
    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
};
find_phrase () {
    # Desc: Filter phrase
    # Usage: cat *.txt | find_phrase
    # Input:  stdin         input lines
    #         CONTEXT_VERB  grep parameter
    # Output: stdout  lines matching grep patterns

    local cmd+=('grep');
    cmd+=('--ignore-case');
    cmd+=('--context' "$CONTEXT_PHRASE");
    cmd+=('--extended-regexp');
    cmd+=('--color=always');
    cmd+=('-e' '( his| her| my) [^\.|;]{,48}( his| her| my) (breast|pussy|tits|nipple|womanhood|cock( |\.|,)|manhood|dick|cunt)');
    cmd+=('-e' '( his| her| my) [^\.|;]{,24}nipple.{,24}harden');
    cmd+=('-e' '(suck|lick)[^\.|;]{,12} (nipple|cock( |\.|,)|dick)');
    cmd+=('-e' '(slap)[^\.|;]{,12}( ass)');
    cmd+=('-e' '( his| her| my) [^\.|;]{,12}(cunt|pussy( |\.|,)|cock( |\.|,)|dick|shaft( |\.|,|;))');
    cmd+=('--');
    cmd+=('-');
    local output; mapfile -t output < <( "${cmd[@]}"; );
    printf "%s\n" "${output[@]}";
    #printf "Found %d matching lines for phrases in %s.\n" "${#output[@]}" "$fin" 1>&2; # debug
}; # find phrase
main () {
    din="$1";
    if [[ ! -d "$din" ]]; then die "FATAL:Not a dir:${din}"; fi;

    find "$din" -type f -name "*.txt" | shuf | head -n "$FIN_MAX" | \
        #parallel search_thread '{}' | less --RAW-CONTROL-CHARS -S;
        parallel search_thread '{}';
};
export -f yell die must search_thread find_nouns find_adjectives find_verbs find_mix_1 find_mix_2 find_phrase;

main "$@";
