/*
 * Copyright (c) 2016-present, RxJava Contributors.
 *
 * 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.
 */

package io.reactivex.rxjava3.validators;

import java.io.*;
import java.util.*;

import org.junit.Test;

import io.reactivex.rxjava3.testsupport.TestHelper;

public class JavadocFindUnescapedAngleBrackets {

    @Test
    public void find() throws Exception {
        File base = TestHelper.findSource("Flowable");

        if (base == null) {
            return;
        }

        base = base.getParentFile().getParentFile();

        Queue<File[]> files = new ArrayDeque<>();

        files.offer(base.listFiles());

        StringBuilder b = new StringBuilder();
        int count = 0;

        while (!files.isEmpty()) {
            for (File file : files.poll()) {
                if (file.getName().endsWith(".java")) {

                    String s = readFile(file);

                    String fn = file.toString().substring(base.toString().length());
                    fn = fn.replace("\\", ".");
                    fn = fn.replace("//", ".");
                    fn = fn.replace(".java", "");
                    fn = "io.reactivex" + fn;

                    int j = 0;
                    for (;;) {
                        int idx = s.indexOf("<code>", j);
                        if (idx < 0) {
                            break;
                        }
                        int jdx = s.indexOf("</code>", idx + 6);

                        int k = idx + 6;
                        for (;;) {
                            int kdx = s.indexOf('>', k);
                            if (kdx < 0) {
                                break;
                            }

                            if (kdx < jdx) {
                                b.append("at ")
                                .append(fn)
                                .append(".gt(")
                                .append(file.getName()).append(":")
                                .append(countLine(s, kdx))
                                .append(")\r\n");
                                count++;
                            } else {
                                break;
                            }
                            k = kdx + 1;
                        }

                        k = idx + 6;
                        for (;;) {
                            int kdx = s.indexOf('<', k);
                            if (kdx < 0) {
                                break;
                            }

                            if (kdx < jdx) {
                                b.append("at ")
                                .append(fn)
                                .append(".lt(")
                                .append(file.getName()).append(":")
                                .append(countLine(s, kdx))
                                .append(")\r\n");
                                count++;
                            } else {
                                break;
                            }
                            k = kdx + 1;
                        }

                        j = jdx + 7;
                    }
                }
            }
        }

        if (b.length() > 0) {
            System.err.println("Should escape < and > in <code> blocks! " + count);
            System.err.println(b);
            throw new Exception("Should escape < and > in <code> blocks! " + count + "\r\n" + b);
        }
    }

    static int countLine(String s, int kdx) {
        int c = 1;
        for (int i = kdx; i >= 0; i--) {
            if (s.charAt(i) == '\n') {
                c++;
            }
        }
        return c;
    }

    static String readFile(File f) throws IOException {
        StringBuilder b = new StringBuilder((int)f.length());
        BufferedReader in = new BufferedReader(new FileReader(f));
        try {
            String line = null;

            while ((line = in.readLine()) != null) {
                b.append(line).append("\n");
            }

        } finally {
            in.close();
        }
        return b.toString();
    }
}
