/*
 * Copyright 2016 Jun-ya HASEBA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

"use strict";

import {parse} from "txt-to-ast";

export default class SatsukiProcessor {

    constructor(config) {
        this.config = config;
    }

    static availableExtensions() {
        return [
            ".txt"
        ];
    }

    static get BLOCK_TAGS() {
        return [
            [/^>>$/, "<<"],
            [/^>>\|$/, "|<<"],
            [/^>>\|\|$/, "||<<"],
            [/^>>\[https?:\/\/[^\]]+\]$/, "<<"],
            [/^>https?:\/\/[^>]+>$/, "<<"],
            [/^>\|$/, "|<"],
            [/^>\|\|$/, "||<"],
            [/^>\|\|#$/, "#||<"],
            [/^>\|\?\|$/, "||<"],
            [/^>\|[^\|]+\|$/, "||<"]
        ];
    }

    processor(ext) {
        return {
            preProcess: (text, filePath) => {
                const result = parse(text);
                this.ignoreLines = new Array(result.loc.end.line);
                this.ignoreColumns = new Array(result.loc.end.line);
                for (let i = 0; i < this.ignoreColumns.length; i++) {
                    this.ignoreColumns[i] = new Array();
                }

                let inBlock = false;
                let endTag = null;
                for (let i = 0; i < result.children.length; i++) {
                    if (!inBlock) {
                        for (let j = 0; j < SatsukiProcessor.BLOCK_TAGS.length; j++) {
                            if (result.children[i].raw.match(SatsukiProcessor.BLOCK_TAGS[j][0])) {
                                inBlock = true;
                                endTag = SatsukiProcessor.BLOCK_TAGS[j][1];
                                break;
                            }
                        }
                    }
                    if (inBlock) {
                        if (result.children[i].raw === endTag) {
                            inBlock = false;
                        }
                        this.ignoreLines[result.children[i].loc.start.line - 1] = true;
                    } else {
                        const regexp = /\[[^\]]+\]/g;
                        let tag = null;
                        while (tag = regexp.exec(result.children[i].raw)) {
                            this.ignoreColumns[result.children[i].loc.start.line - 1].push(
                                [tag.index + 1, regexp.lastIndex]
                            );
                        }
                    }
                }

                return result;
            },
            postProcess: (messages, filePath) => {
                const activeMessages = messages.filter((message) => {
                    if (this.ignoreLines[message.line - 1]) {
                        return false;
                    }
                    for (let i = 0; i < this.ignoreColumns[message.line - 1].length; i++) {
                        const ignoreColumn = this.ignoreColumns[message.line - 1][i];
                        if (ignoreColumn[0] <= message.column && ignoreColumn[1] >= message.column) {
                            return false;
                        }
                    }
                    return true;
                });

                return {
                    messages: activeMessages,
                    filePath: filePath ? filePath : "<text>"
                };
            }
        };
    }
}

@@ -1410,81 +1410,15 @@
 nore
-Lines = new Array(result.loc.end.line);%0A                this.ignoreColumn
+Message
 s = 
@@ -1496,22 +1496,23 @@
 s.ignore
-Column
+Message
 s.length
@@ -1555,32 +1555,33 @@
 nore
-Columns%5Bi%5D = new Array()
+Messages%5Bi%5D = %5Bfalse, %5B%5D%5D
 ;%0A  
@@ -1728,32 +1728,88 @@
 .length; i++) %7B%0A
+                    const element = result.children%5Bi%5D;%0A
                 
@@ -1947,71 +1947,115 @@
     
-if (result.children%5Bi%5D.raw.match(SatsukiProcessor.BLOCK_TAGS%5Bj%5D
+const blockTag = SatsukiProcessor.BLOCK_TAGS%5Bj%5D;%0A                            if (element.raw.match(blockTag
 %5B0%5D)
@@ -2151,38 +2151,16 @@
 g = 
-SatsukiProcessor.BLOCK_TAGS%5Bj%5D
+blockTag
 %5B1%5D;
@@ -2340,34 +2340,23 @@
     if (
-result.children%5Bi%5D
+element
 .raw ===
@@ -2476,32 +2476,24 @@
 nore
-Lines%5Bresult.children%5Bi%5D
+Messages%5Belement
 .loc
@@ -2508,16 +2508,19 @@
 ine - 1%5D
+%5B0%5D
  = true;
@@ -2579,22 +2579,32 @@
   const 
-regexp
+inlineTagPattern
  = /%5C%5B%5B%5E
@@ -2641,17 +2641,23 @@
     let 
-t
+inlineT
 ag = nul
@@ -2694,44 +2694,49 @@
 le (
-tag = regexp.exec(result.children%5Bi%5D
+inlineTag = inlineTagPattern.exec(element
 .raw
@@ -2783,34 +2783,24 @@
 nore
-Columns%5Bresult.children%5Bi%5D
+Messages%5Belement
 .loc
@@ -2813,16 +2813,19 @@
 .line - 
+1%5D%5B
 1%5D.push(
@@ -2858,17 +2858,23 @@
        %5B
-t
+inlineT
 ag.index
@@ -2883,14 +2883,24 @@
  1, 
-regexp
+inlineTagPattern
 .las
@@ -3192,20 +3192,38 @@
         
-if (
+const ignoreMessage = 
 this.ign
@@ -3229,11 +3229,14 @@
 nore
-Lin
+Messag
 es%5Bm
@@ -3251,16 +3251,58 @@
 ine - 1%5D
+;%0A                    if (ignoreMessage%5B0%5D
 ) %7B%0A    
@@ -3401,42 +3401,22 @@
 i %3C 
-this.
 ignore
-Columns%5Bmessage.line - 
+Message%5B
 1%5D.l
@@ -3478,42 +3478,22 @@
 n = 
-this.
 ignore
-Columns%5Bmessage.line - 
+Message%5B
 1%5D%5Bi

Refactor SatsukiProcessor