{{JS_PREFIX}}_supports_keywords = true;
{{JS_PREFIX}}_idle_interval = 4000;

const log = {{PAGE_PREFIX}}_log;

function {{JS_PREFIX}}_getElementsByXPath(xpath, parent) {
    let results = [];
    let query = document.evaluate(xpath, parent || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (let i = 0, length = query.snapshotLength; i < length; ++i) {
        results.push(query.snapshotItem(i));
    }
    return results;
}

const {{JS_PREFIX}}_site_host = location.protocol + '//' + window.location.hostname + '/';

const {{JS_PREFIX}}_jail = document.createElement('div');
{{JS_PREFIX}}_jail.style.display = 'none';

const {{JS_PREFIX}}_site_onload = function () {
    document.getElementsByTagName('body')[0].appendChild({{JS_PREFIX}}_jail);
}

const {{JS_PREFIX}}_appendChild = Element.prototype.appendChild;
Element.prototype.appendChild = function() {
    const node = arguments[0];
    try {
        if (node.tagName) {
            if (node.tagName.toUpperCase() === 'ARTICLE' && node.role && node.role === 'presentation') {
                const block = {{JS_PREFIX}}_should_block({{JS_PREFIX}}_blocked_users, node)
                if (block) {
                    // log('>>> BLOCKING via appendChild: '+block);
                    {{JS_PREFIX}}_appendChild.apply({{JS_PREFIX}}_jail, arguments);
                }
            }
        }
    } catch (e) {
        console.log('>>> error inspecting: e='+e);
    }
    try {
        {{JS_PREFIX}}_appendChild.apply(this, arguments);
    } catch (e) {
        console.log('>>> error calling document.appendChild: arg[0].tagName = '+node.tagName+' e='+e);
    }
};

function {{JS_PREFIX}}_remove_article_from_dom(article, authorName) {
    try {
        if (article.parentElement) {
            // article.innerHTML = '';
            article.parentElement.removeChild(article);
        }
    } catch (e) {
        log('error removing post by author: ' + authorName + ': ' + e);
    }
}

function {{JS_PREFIX}}_is_ad(article) {
    // return typeof Array.from(article.getElementsByTagName('a')).find(a => a.href && a.href.indexOf('/ads/about') !== -1) !== 'undefined';
    return false; // todo: recognize ads
}

function {{JS_PREFIX}}_author_display_name(link) {
    // todo
    return '??';
}

function {{JS_PREFIX}}_remove_article(article, authorName) {
    if (article.className.indexOf('{{JS_PREFIX}}_bub_blocked') === -1) {
        article.className = article.className + ' {{JS_PREFIX}}_bub_blocked';
        {{JS_PREFIX}}_remove_article_from_dom(article, authorName);
    } else {
        log('found post marked removed but still present (??) by author: ' + authorName);
    }
}

function {{JS_PREFIX}}_create_block_control(article, authorName) {
    const imgHolder = {{JS_PREFIX}}_create_block_img();
    const blockSpan = document.createElement('span');
    const blockLink = document.createElement('a');
    blockLink.style.zIndex = '{{APP_CONTROLS_Z_INDEX}}'
    blockLink.style.cursor = 'pointer';
    blockLink.addEventListener("click", function (e) {
        {{JS_PREFIX}}_remove_article_from_dom(article, authorName);
        {{JS_PREFIX}}_block_user(authorName);
        e.stopPropagation();
        e.preventDefault();
        return false;
    });
    blockLink.appendChild(imgHolder);
    blockSpan.appendChild(document.createTextNode('\u00A0\u00A0'));
    blockSpan.appendChild(blockLink);
    blockSpan.id = 'blockSpan_'+{{JS_PREFIX}}_uuidv4();
    // console.log('adding block control on '+authorName);
    return blockSpan;
}

function {{JS_PREFIX}}_is_author_link(href) {
    const non_authors = [];

    let h = href.startsWith({{JS_PREFIX}}_site_host) ? href.substring({{JS_PREFIX}}_site_host.length) : href;
    const qPos = h.indexOf('?');
    if (qPos !== -1) {
        h = h.substring(0, qPos);
    }
    if (h.endsWith('/')) h = h.substring(0, h.length - 1);
    if (non_authors.indexOf(h) !== -1) return false;
    const matches = h.match(/\//g);
    if (matches !== null) {
        // log('>>>>>> not a top-level link: h='+h+', href='+href);
    }
    return matches === null;
}

function {{JS_PREFIX}}_should_block(blocked_users, article) {
    const sitePrefix = {{JS_PREFIX}}_site_host;
    const log = {{PAGE_PREFIX}}_log;

    const firstEval = {{JS_PREFIX}}_mark_evaluated(article);

    if ({{JS_PREFIX}}_includes_block_keyword(article, firstEval)) {
        // log('should_block returning true for keyword block');
        return true;
    }

    const authorLinks = Array.from(article.getElementsByTagName('a'))
        .filter(a => {{JS_PREFIX}}_is_author_link(a.href))
        .filter(a => a.getElementsByTagName('img').length === 0);
    if (authorLinks.length === 0) {
        console.log('author not found');
        return false;
    }
    const authorLink = authorLinks[0];
    let authorHref = authorLink.href;
    let authorName = authorHref.startsWith(sitePrefix) ? authorHref.substring(sitePrefix.length) : authorHref;
    const qPos = authorName.indexOf('?');
    if (qPos !== -1) {
        authorName = authorName.substring(0, qPos);
        authorLink.href = sitePrefix + authorName;
    }
    if (authorName.endsWith('/')) authorName = authorName.substring(0, authorName.length-1);
    const authorDisplayName = authorLink.innerHTML;
    log('should_block checking '+authorName);
    if ({{JS_PREFIX}}_is_ad(article)) {
        // log('removing ad ('+authorDisplayName+')');
        {{JS_PREFIX}}_tally_author_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName);
        if (!firstEval) {{JS_PREFIX}}_untally_allow();
        return authorName == null ? true : authorName;

    } else if (authorName in blocked_users) {
        // log('should_block returning '+authorName);
        {{JS_PREFIX}}_tally_author_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName);
        if (!firstEval) {{JS_PREFIX}}_untally_allow();
        return authorName == null ? true : authorName;

    } else {
        // have we visited this authorLink before?
        try {
            if (authorLink.id === "") {
                // log('VISITING author: ' + authorName + ' (' + authorDisplayName + ')');
                authorLink.id = 'bubble_author_' + {{JS_PREFIX}}_uuidv4();
                // log('assigned id='+authorLink.id+' for authorLink by '+authorName);

            } else if (!firstEval) {
                // log('NOT RE-VISITING article node for author: ' + authorName + ' (' + authorDisplayName + '), display.inner='+authorDisplay.parentNode.innerHTML);
                return false;

            } else {
                // log('RE-VISITING article node for author: ' + authorName + ' (' + authorDisplayName + '), display.inner='+authorDisplay.parentNode.innerHTML);
            }
            let b = {{JS_PREFIX}}_create_block_control(article, authorName);
            // console.log('inserting span='+b.id+' for article by '+authorName);
            authorLink.parentNode.appendChild(b);

        } catch (e) {
            log('badness: '+e);
        }
    }
    if (firstEval) {
        // console.log('>>> allowing post with firstAuthor = '+firstAuthor);
        {{JS_PREFIX}}_tally_allow();
    }
    return false;
}

function {{JS_PREFIX}}_apply_blocks(blocked_users) {

    const articles = {{JS_PREFIX}}_getElementsByXPath('//article');

    for (let i=0; i<articles.length; i++) {
        const article = articles[i];
        const authorName = {{JS_PREFIX}}_should_block(blocked_users, article);
        if (authorName) {
            console.log('calling remove_article with authorName='+authorName);
            {{JS_PREFIX}}_remove_article(article, authorName === true ? null : authorName);
        }
    }
}
