import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class builder{
    private static void generate(File inputDir,File outputDir,String head,String json,String header,String url,File file,ArrayList<String> urls,ArrayList<String[]> arrayList)throws Exception{
        File[] files=file.listFiles();
        if(null!=files)for(File inputFile:files){
            String inputFileName=inputFile.getAbsolutePath().substring(inputDir.getAbsolutePath().length()).replace(File.separator,"/");
            File outputFile=new File(outputDir,inputFile.getAbsolutePath().substring(inputDir.getAbsolutePath().length()));
            if(inputFile.isDirectory()){
                if(!outputFile.exists())outputFile.mkdirs();
                if(inputFileName.matches(".*/(?:architecture|howto|logic|tutorial)")){
                    arrayList=new ArrayList<>();
                    generate(inputDir,outputDir,head,json,header,url,inputFile,urls,arrayList);
                    if(0!=arrayList.size()){
                        String html;
                        file=new File(outputFile,"index.html");
                        try(FileInputStream fileInputStream=new FileInputStream(file)){
                            html=new String(fileInputStream.readAllBytes(),"utf-8");
                        }
                        Matcher matcher=Pattern.compile("<section data-nosnippet></section>").matcher(html);
                        if(matcher.find()){
                            String section="<section data-nosnippet><h2>/"+inputFileName.replaceFirst(".*/","")+"/</h2>";
                            for(String[] array:arrayList)section+="<section><h3><a href='"+array[0]+"'>"+array[1]+"</a></h3>"+array[2]+"</section>";
                            section+="</section>";
                            html=html.replaceFirst(matcher.group(0),Matcher.quoteReplacement(section));
                        }
                        try(FileOutputStream fileOutputStream=new FileOutputStream(file)){
                            fileOutputStream.write(html.getBytes("utf-8"));
                        }
                    }
                }else generate(inputDir,outputDir,head,json,header,url,inputFile,urls,arrayList);
                continue;
            }
            try(FileInputStream fileInputStream=new FileInputStream(inputFile);FileOutputStream fileOutputStream=new FileOutputStream(outputFile)){
                if(inputFile.getName().matches(".*\\.html")){
                    String html="<!doctype html>"+(inputFileName.matches("^/en/.*")?"<html lang='en'>":inputFileName.matches("^/ja/.*")?"<html lang='ja'>":"<html>")+"\r\n"+new String(fileInputStream.readAllBytes(),"utf-8")+"\r\n</html>"
                    ,rootRelativePath=inputFileName.replaceFirst("(?<=/)index\\.html$","").replaceFirst("\\.html$",""),path=url+rootRelativePath;
                    html=html.replaceFirst("<head>",Matcher.quoteReplacement("<head>\r\n"+String.format(head,path))).replaceFirst("<body>",Matcher.quoteReplacement("<body>\r\n<header>"+header+"</header>"));
                    if( inputFileName.matches("^/index\\.html"))html=html.replaceFirst("<a href='/' title='home'><svg version='1.1' viewBox='0 0 1 1'><use xlink:href='/svg/symbols.svg#home'/></svg></a>", "");
                    if( inputFileName.matches("^/index\\.html")
                     || inputFileName.matches("^/(?:en|ja)/index\\.html"))html=html.replaceFirst("(<link rel='canonical' href='[^']+'>)","$1"
                        +Matcher.quoteReplacement(String.format("<link rel='alternate' hreflang='x-default' href='%s/'>"
                                                               +"<link rel='alternate' hreflang='en' href='%s/en/'>"
                                                               +"<link rel='alternate' hreflang='ja' href='%s/ja/'>",url,url,url)));
                    if( inputFileName.matches("^/404\\.html"))html=html.replaceFirst("<link rel='canonical' href='[^']+'>", "");
                    if( inputFileName.matches("^/index\\.html")
                     || inputFileName.matches("^/(?:en|ja)/index\\.html")
                     || inputFileName.matches("^/about/index\\.html")
                     || inputFileName.matches("^/policy/index\\.html")
                     || inputFileName.matches("^/(?:en|ja)/(?!scripting/html/).*"))urls.add("<url><loc>"+path+"</loc></url>");
                    if( inputFileName.matches("^/(?:en|ja)/(?:architecture|howto|logic|tutorial)/.*"))if(!inputFileName.matches(".*/index\\.html")&&null!=arrayList){
                        Matcher matcher=Pattern.compile("<meta name='description' content='([^':]+): ([^']+)'>").matcher(html);
                        if(matcher.find())arrayList.add(new String[]{rootRelativePath.replaceFirst("^/[^/]+/[^/]+/",""),matcher.group(1),matcher.group(2)});
                    }
                    if( inputFileName.matches("^/(?:en|ja)/(?:architecture|howto|logic|tutorial)/.*")
                     || inputFileName.matches("^/(?:en|ja)/scripting/pwa/(?!lunarcalendar/).*")){
                        String enPath=path.replaceFirst("/ja/", "/en/"),jaPath=path.replaceFirst("/en/", "/ja/");
                        html=html.replaceFirst("(<link rel='canonical' href='[^']+'>)","$1"
                        +Matcher.quoteReplacement(String.format("<link rel='alternate' hreflang='x-default' href='%s'>"
                                                               +"<link rel='alternate' hreflang='en' href='%s'>"
                                                               +"<link rel='alternate' hreflang='ja' href='%s'>",enPath,enPath,jaPath)));
                    }
                    if( inputFileName.matches(".*/html/storagemanager/index\\.html"))html=html.replaceFirst("<script src='/js/defer/menu.js' defer>", "");
                    if( inputFileName.matches(".*/html/(?:storagemanager|colorpropertymanager)/index\\.html")
                     || inputFileName.matches(".*/pwa/(?:calendar|lunarcalendar)/index\\.html"))html=html.replaceFirst("<script src='/js/defer/theme.js' defer></script>", "");
                    if(!inputFileName.matches(".*/architecture/(?:cloudflarepagesadvancedmode|reflection)\\.html")
                     &&!inputFileName.matches(".*/logic/reflection\\.html")
                     &&!inputFileName.matches(".*/tutorial/javascript\\.html"))html=html.replaceFirst("<script src='/js/defer/datauri.js' defer></script>", "");
                    if( inputFileName.matches(".*/scripting/pwa/.*")){
                        Matcher matcher=Pattern.compile("<meta name='description' content='([^':]+): ([^']+)'>").matcher(html);
                        if(matcher.find()){
                            try(FileOutputStream jsonStream=new FileOutputStream(new File(outputFile.getParent(),"manifest.json"))){
                                jsonStream.write(String.format(json,matcher.group(1),matcher.group(1)).getBytes("utf-8"));
                            }
                        }
                    }else html=html.replaceFirst("<link rel='manifest' crossorigin='use-credentials' href='manifest.json'><link rel='stylesheet' href='/css/pwa.css'>", "");
                    fileOutputStream.write(html.getBytes("utf-8"));
System.out.println(outputFile);
                }else try(FileChannel fileInputStreamChannel=fileInputStream.getChannel();WritableByteChannel outputStreamChannel=Channels.newChannel(fileOutputStream)){
                    long length=fileInputStreamChannel.size(),position=0;
                    try{
                        while(position<length)position+=fileInputStreamChannel.transferTo(position,length-position,outputStreamChannel);
                    }catch(Exception e){
System.out.println(e);
                    }
                }
            }
        }
    }
    public static void main(String[] args)throws Exception{
        if(3>args.length)return;
        File inputDir=new File(args[0]).getAbsoluteFile(),outputDir=new File(args[1]).getAbsoluteFile();
        String url=args[2];
        if(!outputDir.exists())outputDir.mkdirs();
        ArrayList<String> urls=new ArrayList<>();
        try(FileInputStream headStream=new FileInputStream(new File(inputDir,"txt/head.txt"));
            FileInputStream headerStream=new FileInputStream(new File(inputDir,"txt/header.txt"));
            FileInputStream jsonStream=new FileInputStream(new File(inputDir,"txt/manifest.txt"))){
            String head=new String(headStream.readAllBytes(),"utf-8"),header=new String(headerStream.readAllBytes(),"utf-8"),json=new String(jsonStream.readAllBytes(),"utf-8");
            generate(inputDir,outputDir,head,json,header,url,inputDir,urls,null);
        }
        try(FileInputStream fileInputStream=new FileInputStream(new File(inputDir,"sitemap.xml"));FileOutputStream fileOutputStream=new FileOutputStream(new File(outputDir,"sitemap.xml"))){
            String xml=new String(fileInputStream.readAllBytes(),"utf-8");
            xml=xml.replaceFirst("<url></url>",Matcher.quoteReplacement(String.join("",urls)));
            fileOutputStream.write(xml.getBytes("utf-8"));
        }
    }
}