<commit_before>package com.github.kongchen.swagger.docgen;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.helper.StringHelpers;
import com.github.jknack.handlebars.io.TemplateLoader;
import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource;
import com.github.kongchen.swagger.docgen.reader.ModelSubstitute;
import io.swagger.converter.ModelConverters;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import org.apache.commons.io.FileUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: chekong 05/13/2013
 */
public abstract class AbstractDocumentSource {
    protected final ApiSource apiSource;

    protected final LogAdapter LOG;

    private final String outputPath;

    private final String templatePath;

    private final String swaggerPath;

    private final String modelSubstitute;
    
    protected final List<Type> typesToSkip = new ArrayList<Type>();

    protected Swagger swagger;

    private ObjectMapper mapper = new ObjectMapper();
    private boolean isSorted = false;

    protected String swaggerSchemaConverter;

    public AbstractDocumentSource(LogAdapter log, ApiSource apiSource) {
        LOG = log;
        this.outputPath = apiSource.getOutputPath();
        this.templatePath = apiSource.getTemplatePath();
        this.swaggerPath = apiSource.getSwaggerDirectory();
        this.modelSubstitute = apiSource.getModelSubstitute();

        swagger = new Swagger();
        if (apiSource.getSchemes() != null) {
            if (apiSource.getSchemes().contains(",")) {
                for (String scheme : apiSource.getSchemes().split(",")) {
                    swagger.scheme(Scheme.forValue(scheme));
                }
            } else {
                swagger.scheme(Scheme.forValue(apiSource.getSchemes()));
            }
        }

        swagger.setHost(apiSource.getHost());
        swagger.setInfo(apiSource.getInfo());
        swagger.setBasePath(apiSource.getBasePath());

        this.apiSource = apiSource;
    }


    public abstract void loadDocuments() throws Exception, GenerateException;

    public void toSwaggerDocuments(String swaggerUIDocBasePath)
            throws GenerateException {
        mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        if (swaggerPath == null) {
            return;
        }
        if (!isSorted) {
            Utils.sortSwagger(swagger);
            isSorted = true;
        }
        File dir = new File(swaggerPath);
        if (dir.isFile()) {
            throw new GenerateException(String.format(
                    "Swagger-outputDirectory[%s] must be a directory!",
                    swaggerPath));
        }

        if (!dir.exists()) {
            try {
                FileUtils.forceMkdir(dir);
            } catch (IOException e) {
                throw new GenerateException(String.format(
                        "Create Swagger-outputDirectory[%s] failed.",
                        swaggerPath));
            }
        }
        cleanupOlds(dir);

        File swaggerFile = new File(dir, "swagger.json");
        try {
            ObjectWriter jsonWriter = mapper.writer(new DefaultPrettyPrinter());
            jsonWriter.writeValue(swaggerFile, swagger);
        } catch (IOException e) {
            throw new GenerateException(e);
        }
    }

    public void loadOverridingModels() throws GenerateException {
        if (modelSubstitute != null) {
            ModelSubstitute modelSubstitute = new ModelSubstitute(new ObjectMapper());
            BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(this.modelSubstitute)));
            String line = null;
            try {
                line = reader.readLine();
                while (line != null) {
                    String[] classes = line.split(":");
                    if (classes == null || classes.length != 2) {
                        throw new GenerateException("Bad format of override model file, it should be ${actualClassName}:${expectClassName}");
                    }
                    modelSubstitute.substitute(classes[0].trim(), classes[1].trim());
                    line = reader.readLine();
                }
            } catch (IOException e) {
                throw new GenerateException(e);
            }
            ModelConverters.getInstance().addConverter(modelSubstitute);
        }
    }
    
    public void loadTypesToSkip() throws GenerateException {
        List<String> typesToSkip = apiSource.getTypesToSkip();
        if (typesToSkip != null && !typesToSkip.isEmpty()) {
            ObjectMapper mapper = new ObjectMapper();
            for (String typeToSkip : typesToSkip) {
                try {
                    Type type = Class.forName(typeToSkip);
                    this.typesToSkip.add(type);
                } catch (ClassNotFoundException e) {
                    throw new GenerateException(e);
                }
            }
        }
    }
    
    

    private void cleanupOlds(File dir) {
        if (dir.listFiles() != null) {
            for (File f : dir.listFiles()) {
                if (f.getName().endsWith("json") || f.getName().endsWith("html")) {
                    f.delete();
                }
            }
        }
    }

    private void writeInDirectory(File dir, Swagger swaggerDoc,
                                  String basePath) throws GenerateException {

//		try {
//			File serviceFile = createFile(dir, filename);
//			String json = JsonSerializer.asJson(swaggerDoc);
//			JsonNode tree = mapper.readTree(json);
//			if (basePath != null) {
//				((ObjectNode) tree).put("basePath", basePath);
//			}
//
//			JsonUtil.mapper().writerWithDefaultPrettyPrinter()
//					.writeValue(serviceFile, tree);
//		} catch (IOException e) {
//			throw new GenerateException(e);
//		}<commit_msg>Revert "Cleaning up old document.html files per build"<commit_after>package com.github.kongchen.swagger.docgen;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.helper.StringHelpers;
import com.github.jknack.handlebars.io.TemplateLoader;
import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource;
import com.github.kongchen.swagger.docgen.reader.ModelSubstitute;
import io.swagger.converter.ModelConverters;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import org.apache.commons.io.FileUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: chekong 05/13/2013
 */
public abstract class AbstractDocumentSource {
    protected final ApiSource apiSource;

    protected final LogAdapter LOG;

    private final String outputPath;

    private final String templatePath;

    private final String swaggerPath;

    private final String modelSubstitute;
    
    protected final List<Type> typesToSkip = new ArrayList<Type>();

    protected Swagger swagger;

    private ObjectMapper mapper = new ObjectMapper();
    private boolean isSorted = false;

    protected String swaggerSchemaConverter;

    public AbstractDocumentSource(LogAdapter log, ApiSource apiSource) {
        LOG = log;
        this.outputPath = apiSource.getOutputPath();
        this.templatePath = apiSource.getTemplatePath();
        this.swaggerPath = apiSource.getSwaggerDirectory();
        this.modelSubstitute = apiSource.getModelSubstitute();

        swagger = new Swagger();
        if (apiSource.getSchemes() != null) {
            if (apiSource.getSchemes().contains(",")) {
                for (String scheme : apiSource.getSchemes().split(",")) {
                    swagger.scheme(Scheme.forValue(scheme));
                }
            } else {
                swagger.scheme(Scheme.forValue(apiSource.getSchemes()));
            }
        }

        swagger.setHost(apiSource.getHost());
        swagger.setInfo(apiSource.getInfo());
        swagger.setBasePath(apiSource.getBasePath());

        this.apiSource = apiSource;
    }


    public abstract void loadDocuments() throws Exception, GenerateException;

    public void toSwaggerDocuments(String swaggerUIDocBasePath)
            throws GenerateException {
        mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        if (swaggerPath == null) {
            return;
        }
        if (!isSorted) {
            Utils.sortSwagger(swagger);
            isSorted = true;
        }
        File dir = new File(swaggerPath);
        if (dir.isFile()) {
            throw new GenerateException(String.format(
                    "Swagger-outputDirectory[%s] must be a directory!",
                    swaggerPath));
        }

        if (!dir.exists()) {
            try {
                FileUtils.forceMkdir(dir);
            } catch (IOException e) {
                throw new GenerateException(String.format(
                        "Create Swagger-outputDirectory[%s] failed.",
                        swaggerPath));
            }
        }
        cleanupOlds(dir);

        File swaggerFile = new File(dir, "swagger.json");
        try {
            ObjectWriter jsonWriter = mapper.writer(new DefaultPrettyPrinter());
            jsonWriter.writeValue(swaggerFile, swagger);
        } catch (IOException e) {
            throw new GenerateException(e);
        }
    }

    public void loadOverridingModels() throws GenerateException {
        if (modelSubstitute != null) {
            ModelSubstitute modelSubstitute = new ModelSubstitute(new ObjectMapper());
            BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(this.modelSubstitute)));
            String line = null;
            try {
                line = reader.readLine();
                while (line != null) {
                    String[] classes = line.split(":");
                    if (classes == null || classes.length != 2) {
                        throw new GenerateException("Bad format of override model file, it should be ${actualClassName}:${expectClassName}");
                    }
                    modelSubstitute.substitute(classes[0].trim(), classes[1].trim());
                    line = reader.readLine();
                }
            } catch (IOException e) {
                throw new GenerateException(e);
            }
            ModelConverters.getInstance().addConverter(modelSubstitute);
        }
    }
    
    public void loadTypesToSkip() throws GenerateException {
        List<String> typesToSkip = apiSource.getTypesToSkip();
        if (typesToSkip != null && !typesToSkip.isEmpty()) {
            ObjectMapper mapper = new ObjectMapper();
            for (String typeToSkip : typesToSkip) {
                try {
                    Type type = Class.forName(typeToSkip);
                    this.typesToSkip.add(type);
                } catch (ClassNotFoundException e) {
                    throw new GenerateException(e);
                }
            }
        }
    }
    
    

    private void cleanupOlds(File dir) {
        if (dir.listFiles() != null) {
            for (File f : dir.listFiles()) {
                if (f.getName().endsWith("json")) {
                    f.delete();
                }
            }
        }
    }

    private void writeInDirectory(File dir, Swagger swaggerDoc,
                                  String basePath) throws GenerateException {

//		try {
//			File serviceFile = createFile(dir, filename);
//			String json = JsonSerializer.asJson(swaggerDoc);
//			JsonNode tree = mapper.readTree(json);
//			if (basePath != null) {
//				((ObjectNode) tree).put("basePath", basePath);
//			}
//
//			JsonUtil.mapper().writerWithDefaultPrettyPrinter()
//					.writeValue(serviceFile, tree);
//		} catch (IOException e) {
//			throw new GenerateException(e);
//		}
{'fraction_non_alphanumeric': 0.10382997564755368, 'fraction_numerical': 0.0016234964209283448, 'mean_word_length': 2.3469992590763153, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1697073', 'n_tokens_mistral': 3775, 'n_tokens_neox': 3573, 'n_words': 738}