/*-
 * ~~~~~~licensing~~~~~~
 * core-support-design
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.core.support.design.openapi.utils;

import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.StringTokenizer;

public class CompilationUnit implements ICompilationUnit {

    public static final int BUFFER_SIZE = 8192;
    private final String className;
    private final String sourceFile;
    private final String ignoredPart;

    private static final Logger log = LoggerFactory.getLogger(CompilationUnit.class);

    public CompilationUnit(String sourceFile, String className, String ignoredPart) {
        this.className = className;
        this.sourceFile = sourceFile;
        this.ignoredPart = ignoredPart;
    }

    @Override
    public char[] getFileName() {
        int i = sourceFile.indexOf(ignoredPart);
        String result = sourceFile;
        if (i >= 0) {
            result = result.substring(i + ignoredPart.length());
        }
        return result.toCharArray();
    }

    @Override
    public char[] getContents() {
        char[] result = null;
        try (FileInputStream is = new FileInputStream(sourceFile);
             InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
             Reader reader = new BufferedReader(isr)) {
            char[] chars = new char[BUFFER_SIZE];
            StringBuilder source = new StringBuilder();
            int count;
            while ((count = reader.read(chars, 0, chars.length)) > 0) {
                source.append(chars, 0, count);
            }
            result = new char[source.length()];
            source.getChars(0, result.length, result, 0);
        } catch (IOException e) {
            log.error("Failed to get source file {} contents", sourceFile, e);
        }
        return result;
    }

    @Override
    public char[] getMainTypeName() {
        int dot = className.lastIndexOf('.');
        if (dot > 0) {
            return className.substring(dot + 1).toCharArray();
        }
        return className.toCharArray();
    }

    @Override
    public char[][] getPackageName() {
        StringTokenizer st = new StringTokenizer(className, ".");
        char[][] result = new char[st.countTokens() - 1][];
        for (int i = 0; i < result.length; i++) {
            String token = st.nextToken();
            result[i] = token.toCharArray();
        }
        return result;
    }

    public static ICompilationUnit build(Path fullPath, String containingDir) {
        Path name = fullPath.getFileName();
        String directory = fullPath.toString();
        int i = directory.indexOf(containingDir);
        if (i != -1) {
            String packageDir = directory
                    .substring(i + containingDir.length())
                    .replace(name.toString(), "").replace('\\', '/');
            String className = name.toString().replaceAll(".java$", "");
            if (!packageDir.endsWith("/")) {
                packageDir = packageDir + "/";
            }
            if (packageDir.startsWith("/")) {
                packageDir = packageDir.substring(1);
            }
            return new CompilationUnit(fullPath.toString(), packageDir.replaceAll("/", ".") + className, containingDir);
        }
        return null;
    }
}
