// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import com.azure.autorest.customization.ClassCustomization;
import com.azure.autorest.customization.Customization;
import com.azure.autorest.customization.Editor;
import com.azure.autorest.customization.LibraryCustomization;
import com.azure.autorest.customization.PackageCustomization;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import org.slf4j.Logger;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Contains customizations for Azure KeyVault's RBAC swagger code generation.
 */
public class RbacCustomizations extends Customization {
    @Override
    public void customize(LibraryCustomization libraryCustomization, Logger logger) {
        customizeModels(libraryCustomization.getPackage("com.azure.security.keyvault.administration.models"));
        customizePackageInfos(libraryCustomization.getRawEditor());
    }

    private static void customizeModels(PackageCustomization packageCustomization) {
        customizeKeyVaultRoleScope(packageCustomization.getClass("KeyVaultRoleScope"));
    }

    private static void customizeKeyVaultRoleScope(ClassCustomization classCustomization) {
        classCustomization.customizeAst(ast -> {
            ast.addImport(IllegalArgumentException.class)
                .addImport(URL.class)
                .addImport(MalformedURLException.class);

            ClassOrInterfaceDeclaration clazz = ast.getClassByName(classCustomization.getClassName()).get();

            clazz.addMethod("fromUrl", Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC)
                .setType("KeyVaultRoleScope")
                .addParameter("String", "url")
                .setJavadocComment(StaticJavaParser.parseJavadoc(joinWithNewline(
                    "/**",
                    " * Creates of finds a {@link KeyVaultRoleScope} from its string representation.",
                    " *",
                    " * @param url A string representing a URL containing the name of the scope to look for.",
                    " * @return The corresponding {@link KeyVaultRoleScope}.",
                    " * @throws IllegalArgumentException If the given {@code url} is malformed.",
                    " */"
                )))
                .setBody(StaticJavaParser.parseBlock(joinWithNewline(
                    "{",
                    "try {",
                    "    return fromString(new URL(url).getPath());",
                    "} catch (MalformedURLException e) {",
                    "    throw new IllegalArgumentException(e);",
                    "}",
                    "}"
                )));

            clazz.addMethod("fromUrl", Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC)
                .setType("KeyVaultRoleScope")
                .addParameter("URL", "url")
                .setJavadocComment(StaticJavaParser.parseJavadoc(joinWithNewline(
                    "/**",
                    " * Creates of finds a {@link KeyVaultRoleScope} from its string representation.",
                    " *",
                    " * @param url A URL containing the name of the scope to look for.",
                    " * @return The corresponding {@link KeyVaultRoleScope}.",
                    " */"
                )))
                .setBody(StaticJavaParser.parseBlock("{return fromString(url.getPath());}"));
        });
    }

    private static void customizePackageInfos(Editor editor) {
        editor.replaceFile("src/main/java/com/azure/security/keyvault/administration/package-info.java",
            joinWithNewline(
                "// Copyright (c) Microsoft Corporation. All rights reserved.",
                "// Licensed under the MIT License.",
                "// Code generated by Microsoft (R) AutoRest Code Generator.",
                "",
                "/**",
                " * Package containing classes for creating clients {@link",
                " * com.azure.security.keyvault.administration.KeyVaultAccessControlAsyncClient} and {@link",
                " * com.azure.security.keyvault.administration.KeyVaultAccessControlClient} that perform access control operations on",
                " * Azure Key Vault resources, as well as clients {@link",
                " * com.azure.security.keyvault.administration.KeyVaultBackupAsyncClient} and {@link",
                " * com.azure.security.keyvault.administration.KeyVaultBackupClient} that perform backup and restore operations on Azure",
                " * Key Vault keys.",
                " */",
                "package com.azure.security.keyvault.administration;",
                ""
            ));

        editor.replaceFile("src/main/java/com/azure/security/keyvault/administration/models/package-info.java",
            joinWithNewline(
                "// Copyright (c) Microsoft Corporation. All rights reserved.",
                "// Licensed under the MIT License.",
                "// Code generated by Microsoft (R) AutoRest Code Generator.",
                "",
                "/**",
                " * Package containing classes used by {@link",
                " * com.azure.security.keyvault.administration.KeyVaultAccessControlAsyncClient} and {@link",
                " * com.azure.security.keyvault.administration.KeyVaultAccessControlClient} to perform access control operations on Azure",
                " * Key Vault resources, as well as classes used by {@link",
                " * com.azure.security.keyvault.administration.KeyVaultBackupAsyncClient} and {@link",
                " * com.azure.security.keyvault.administration.KeyVaultBackupClient} to perform backup and restore operations on Azure",
                " * Key Vault keys.",
                " */",
                "package com.azure.security.keyvault.administration.models;",
                ""
            ));

        editor.replaceFile("src/main/java/com/azure/security/keyvault/administration/implementation/package-info.java",
            joinWithNewline(
                "// Copyright (c) Microsoft Corporation. All rights reserved.",
                "// Licensed under the MIT License.",
                "// Code generated by Microsoft (R) AutoRest Code Generator.",
                "",
                "/**",
                " * Package containing the implementations for KeyVaultAccessControlClient, KeyVaultBackupClient, and",
                " * KeyVaultSettingsClient. The key vault client performs cryptographic key operations and vault operations against the",
                " * Key Vault service.",
                " */",
                "package com.azure.security.keyvault.administration.implementation;",
                ""
            ));

        editor.replaceFile("src/main/java/com/azure/security/keyvault/administration/implementation/models/package-info.java",
            joinWithNewline(
                "// Copyright (c) Microsoft Corporation. All rights reserved.",
                "// Licensed under the MIT License.",
                "// Code generated by Microsoft (R) AutoRest Code Generator.",
                "",
                "/**",
                " * Package containing the data models for KeyVaultAccessControlClient, KeyVaultBackupClient, and KeyVaultSettingsClient.",
                " * The key vault client performs cryptographic key operations and vault operations against the Key Vault service.",
                " */",
                "package com.azure.security.keyvault.administration.implementation.models;",
                ""
            ));
    }

    private static String joinWithNewline(String... lines) {
        return String.join("\n", lines);
    }
}
