// AppLovin MAX Unity Plugin
//
// Created by Santosh Bagadi on 9/3/19.
// Copyright © 2019 AppLovin. All rights reserved.
//
#if UNITY_ANDROID
using System.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Networking;
using Debug = UnityEngine.Debug;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
// [Serializable]
// public class AppLovinQualityServiceData
// {
// public string api_key;
// }
// ///
// /// Adds or updates the AppLovin Quality Service plugin to the provided build.gradle file.
// /// If the gradle file already has the plugin, the API key is updated.
// ///
// public abstract class AppLovinProcessGradleBuildFile
// {
// private static readonly Regex TokenBuildScriptRepositories = new Regex(".*repositories.*");
// private static readonly Regex TokenBuildScriptDependencies = new Regex(".*classpath \'com.android.tools.build:gradle.*");
// private static readonly Regex TokenApplicationPlugin = new Regex(".*apply plugin: \'com.android.application\'.*");
// private static readonly Regex TokenApiKey = new Regex(".*apiKey.*");
// private static readonly Regex TokenAppLovinPlugin = new Regex(".*apply plugin:.+?(?=applovin-quality-service).*");
// #if UNITY_2022_2_OR_NEWER
// private const string PluginsMatcher = "plugins";
// private const string PluginManagementMatcher = "pluginManagement";
// private const string QualityServicePluginRoot = " id 'com.applovin.quality' version '+' apply false // NOTE: Requires version 4.8.3+ for Gradle version 7.2+";
// #endif
// private const string BuildScriptMatcher = "buildscript";
// private const string QualityServiceMavenRepo = "maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }";
// private const string QualityServiceDependencyClassPath = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'";
// private const string QualityServiceApplyPlugin = "apply plugin: 'applovin-quality-service'";
// private const string QualityServicePlugin = "applovin {";
// private const string QualityServiceApiKey = " apiKey '{0}'";
// private const string QualityServiceBintrayMavenRepo = "https://applovin.bintray.com/Quality-Service";
// private const string QualityServiceNoRegexMavenRepo = "maven { url 'https://artifacts.applovin.com/android' }";
// // Legacy plugin detection variables
// private const string QualityServiceDependencyClassPathV3 = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:3.+'";
// private static readonly Regex TokenSafeDkLegacyApplyPlugin = new Regex(".*apply plugin:.+?(?=safedk).*");
// private const string SafeDkLegacyPlugin = "safedk {";
// private const string SafeDkLegacyMavenRepo = "http://download.safedk.com";
// private const string SafeDkLegacyDependencyClassPath = "com.safedk:SafeDKGradlePlugin:";
// ///
// /// Updates the provided Gradle script to add Quality Service plugin.
// ///
// /// The gradle file to update.
// protected void AddAppLovinQualityServicePlugin(string applicationGradleBuildFilePath)
// {
// if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
// var sdkKey = AppLovinSettings.Instance.SdkKey;
// if (string.IsNullOrEmpty(sdkKey))
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager.");
// return;
// }
// // Retrieve the API Key using the SDK Key.
// var qualityServiceData = RetrieveQualityServiceData(sdkKey);
// var apiKey = qualityServiceData.api_key;
// if (string.IsNullOrEmpty(apiKey))
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. API Key is empty.");
// return;
// }
// // Generate the updated Gradle file that needs to be written.
// var lines = File.ReadAllLines(applicationGradleBuildFilePath).ToList();
// var sanitizedLines = RemoveLegacySafeDkPlugin(lines);
// var outputLines = GenerateUpdatedBuildFileLines(
// sanitizedLines,
// apiKey,
// #if UNITY_2019_3_OR_NEWER
// false // On Unity 2019.3+, the buildscript closure related lines will to be added to the root build.gradle file.
// #else
// true
// #endif
// );
// // outputLines can be null if we couldn't add the plugin.
// if (outputLines == null) return;
// try
// {
// File.WriteAllText(applicationGradleBuildFilePath, string.Join("\n", outputLines.ToArray()) + "\n");
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Gradle file write failed.");
// Console.WriteLine(exception);
// }
// }
// #if UNITY_2022_2_OR_NEWER
// ///
// /// Adds AppLovin Quality Service plugin DSL element to the project's root build.gradle file.
// ///
// /// The path to project's root build.gradle file.
// /// true when the plugin was added successfully.
// protected bool AddPluginToRootGradleBuildFile(string rootGradleBuildFile)
// {
// var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
// var outputLines = new List();
// var pluginAdded = false;
// var insidePluginsClosure = false;
// foreach (var line in lines)
// {
// if (line.Contains(PluginsMatcher))
// {
// insidePluginsClosure = true;
// }
// if (!pluginAdded && insidePluginsClosure && line.Contains("}"))
// {
// outputLines.Add(QualityServicePluginRoot);
// pluginAdded = true;
// insidePluginsClosure = false;
// }
// outputLines.Add(line);
// }
// if (!pluginAdded)
// {
// MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin to root gradle file.");
// return false;
// }
// try
// {
// File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
// Console.WriteLine(exception);
// return false;
// }
// return true;
// }
// ///
// /// Adds the AppLovin maven repository to the project's settings.gradle file.
// ///
// /// The path to the project's settings.gradle file.
// /// true if the repository was added successfully.
// protected bool AddAppLovinRepository(string settingsGradleFile)
// {
// var lines = File.ReadLines(settingsGradleFile).ToList();
// var outputLines = new List();
// var mavenRepoAdded = false;
// var pluginManagementClosureDepth = 0;
// var insidePluginManagementClosure = false;
// var pluginManagementMatched = false;
// foreach (var line in lines)
// {
// outputLines.Add(line);
// if (!pluginManagementMatched && line.Contains(PluginManagementMatcher))
// {
// pluginManagementMatched = true;
// insidePluginManagementClosure = true;
// }
// if (insidePluginManagementClosure)
// {
// if (line.Contains("{"))
// {
// pluginManagementClosureDepth++;
// }
// if (line.Contains("}"))
// {
// pluginManagementClosureDepth--;
// }
// if (pluginManagementClosureDepth == 0)
// {
// insidePluginManagementClosure = false;
// }
// }
// if (insidePluginManagementClosure)
// {
// if (!mavenRepoAdded && TokenBuildScriptRepositories.IsMatch(line))
// {
// outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
// mavenRepoAdded = true;
// }
// }
// }
// if (!mavenRepoAdded)
// {
// MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin maven repo to settings gradle file.");
// return false;
// }
// try
// {
// File.WriteAllText(settingsGradleFile, string.Join("\n", outputLines.ToArray()) + "\n");
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Setting Gradle file write failed.");
// Console.WriteLine(exception);
// return false;
// }
// return true;
// }
// #endif
// #if UNITY_2019_3_OR_NEWER
// ///
// /// Adds the necessary AppLovin Quality Service dependency and maven repo lines to the provided root build.gradle file.
// ///
// /// The root build.gradle file path
// /// true if the build script lines were applied correctly.
// protected bool AddQualityServiceBuildScriptLines(string rootGradleBuildFile)
// {
// var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
// var outputLines = GenerateUpdatedBuildFileLines(lines, null, true);
// // outputLines will be null if we couldn't add the build script lines.
// if (outputLines == null) return false;
// try
// {
// File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
// Console.WriteLine(exception);
// return false;
// }
// return true;
// }
// ///
// /// Removes the AppLovin Quality Service Plugin or Legacy SafeDK plugin from the given gradle template file if either of them are present.
// ///
// /// The gradle template file from which to remove the plugin from
// protected static void RemoveAppLovinQualityServiceOrSafeDkPlugin(string gradleTemplateFile)
// {
// var lines = File.ReadAllLines(gradleTemplateFile).ToList();
// lines = RemoveLegacySafeDkPlugin(lines);
// lines = RemoveAppLovinQualityServicePlugin(lines);
// try
// {
// File.WriteAllText(gradleTemplateFile, string.Join("\n", lines.ToArray()) + "\n");
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to remove AppLovin Quality Service Plugin from mainTemplate.gradle. Please remove the Quality Service plugin from the mainTemplate.gradle manually.");
// Console.WriteLine(exception);
// }
// }
// #endif
// private static AppLovinQualityServiceData RetrieveQualityServiceData(string sdkKey)
// {
// var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey);
// var bodyRaw = Encoding.UTF8.GetBytes(postJson);
// // Upload handler is automatically disposed when UnityWebRequest is disposed
// var uploadHandler = new UploadHandlerRaw(bodyRaw);
// uploadHandler.contentType = "application/json";
// using (var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/cred"))
// {
// unityWebRequest.method = UnityWebRequest.kHttpVerbPOST;
// unityWebRequest.uploadHandler = uploadHandler;
// unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
// #if UNITY_2017_2_OR_NEWER
// var operation = unityWebRequest.SendWebRequest();
// #else
// var operation = webRequest.Send();
// #endif
// // Wait for the download to complete or the request to timeout.
// while (!operation.isDone) { }
// #if UNITY_2020_1_OR_NEWER
// if (unityWebRequest.result != UnityWebRequest.Result.Success)
// #elif UNITY_2017_2_OR_NEWER
// if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
// #else
// if (webRequest.isError)
// #endif
// {
// MaxSdkLogger.UserError("Failed to retrieve API Key for SDK Key: " + sdkKey + "with error: " + unityWebRequest.error);
// return new AppLovinQualityServiceData();
// }
// try
// {
// return JsonUtility.FromJson(unityWebRequest.downloadHandler.text);
// }
// catch (Exception exception)
// {
// MaxSdkLogger.UserError("Failed to parse API Key." + exception);
// return new AppLovinQualityServiceData();
// }
// }
// }
// private static List RemoveLegacySafeDkPlugin(List lines)
// {
// return RemovePlugin(lines, SafeDkLegacyPlugin, SafeDkLegacyMavenRepo, SafeDkLegacyDependencyClassPath, TokenSafeDkLegacyApplyPlugin);
// }
// private static List RemoveAppLovinQualityServicePlugin(List lines)
// {
// return RemovePlugin(lines, QualityServicePlugin, QualityServiceMavenRepo, QualityServiceDependencyClassPath, TokenAppLovinPlugin);
// }
// private static List RemovePlugin(List lines, string pluginLine, string mavenRepo, string dependencyClassPath, Regex applyPluginToken)
// {
// var sanitizedLines = new List();
// var legacyRepoRemoved = false;
// var legacyDependencyClassPathRemoved = false;
// var legacyPluginRemoved = false;
// var legacyPluginMatched = false;
// var insideLegacySafeDkClosure = false;
// foreach (var line in lines)
// {
// if (!legacyPluginMatched && line.Contains(pluginLine))
// {
// legacyPluginMatched = true;
// insideLegacySafeDkClosure = true;
// }
// if (insideLegacySafeDkClosure && line.Contains("}"))
// {
// insideLegacySafeDkClosure = false;
// continue;
// }
// if (insideLegacySafeDkClosure)
// {
// continue;
// }
// if (!legacyRepoRemoved && line.Contains(mavenRepo))
// {
// legacyRepoRemoved = true;
// continue;
// }
// if (!legacyDependencyClassPathRemoved && line.Contains(dependencyClassPath))
// {
// legacyDependencyClassPathRemoved = true;
// continue;
// }
// if (!legacyPluginRemoved && applyPluginToken.IsMatch(line))
// {
// legacyPluginRemoved = true;
// continue;
// }
// sanitizedLines.Add(line);
// }
// return sanitizedLines;
// }
// private static List GenerateUpdatedBuildFileLines(List lines, string apiKey, bool addBuildScriptLines)
// {
// var addPlugin = !string.IsNullOrEmpty(apiKey);
// // A sample of the template file.
// // ...
// // allprojects {
// // repositories {**ARTIFACTORYREPOSITORY**
// // google()
// // jcenter()
// // flatDir {
// // dirs 'libs'
// // }
// // }
// // }
// //
// // apply plugin: 'com.android.application'
// // **APPLY_PLUGINS**
// //
// // dependencies {
// // implementation fileTree(dir: 'libs', include: ['*.jar'])
// // **DEPS**}
// // ...
// var outputLines = new List();
// // Check if the plugin exists, if so, update the SDK Key.
// var pluginExists = lines.Any(line => TokenAppLovinPlugin.IsMatch(line));
// if (pluginExists)
// {
// var pluginMatched = false;
// var insideAppLovinClosure = false;
// var updatedApiKey = false;
// var mavenRepoUpdated = false;
// var dependencyClassPathUpdated = false;
// foreach (var line in lines)
// {
// // Bintray maven repo is no longer being used. Update to s3 maven repo with regex check
// if (!mavenRepoUpdated && (line.Contains(QualityServiceBintrayMavenRepo) || line.Contains(QualityServiceNoRegexMavenRepo)))
// {
// outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
// mavenRepoUpdated = true;
// continue;
// }
// // We no longer use version specific dependency class path. Just use + for version to always pull the latest.
// if (!dependencyClassPathUpdated && line.Contains(QualityServiceDependencyClassPathV3))
// {
// outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
// dependencyClassPathUpdated = true;
// continue;
// }
// if (!pluginMatched && line.Contains(QualityServicePlugin))
// {
// insideAppLovinClosure = true;
// pluginMatched = true;
// }
// if (insideAppLovinClosure && line.Contains("}"))
// {
// insideAppLovinClosure = false;
// }
// // Update the API key.
// if (insideAppLovinClosure && !updatedApiKey && TokenApiKey.IsMatch(line))
// {
// outputLines.Add(string.Format(QualityServiceApiKey, apiKey));
// updatedApiKey = true;
// }
// // Keep adding the line until we find and update the plugin.
// else
// {
// outputLines.Add(line);
// }
// }
// }
// // Plugin hasn't been added yet, add it.
// else
// {
// var buildScriptClosureDepth = 0;
// var insideBuildScriptClosure = false;
// var buildScriptMatched = false;
// var qualityServiceRepositoryAdded = false;
// var qualityServiceDependencyClassPathAdded = false;
// var qualityServicePluginAdded = false;
// foreach (var line in lines)
// {
// // Add the line to the output lines.
// outputLines.Add(line);
// // Check if we need to add the build script lines and add them.
// if (addBuildScriptLines)
// {
// if (!buildScriptMatched && line.Contains(BuildScriptMatcher))
// {
// buildScriptMatched = true;
// insideBuildScriptClosure = true;
// }
// // Match the parenthesis to track if we are still inside the buildscript closure.
// if (insideBuildScriptClosure)
// {
// if (line.Contains("{"))
// {
// buildScriptClosureDepth++;
// }
// if (line.Contains("}"))
// {
// buildScriptClosureDepth--;
// }
// if (buildScriptClosureDepth == 0)
// {
// insideBuildScriptClosure = false;
// // There may be multiple buildscript closures and we need to keep looking until we added both the repository and classpath.
// buildScriptMatched = qualityServiceRepositoryAdded && qualityServiceDependencyClassPathAdded;
// }
// }
// if (insideBuildScriptClosure)
// {
// // Add the build script dependency repositories.
// if (!qualityServiceRepositoryAdded && TokenBuildScriptRepositories.IsMatch(line))
// {
// outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
// qualityServiceRepositoryAdded = true;
// }
// // Add the build script dependencies.
// else if (!qualityServiceDependencyClassPathAdded && TokenBuildScriptDependencies.IsMatch(line))
// {
// outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
// qualityServiceDependencyClassPathAdded = true;
// }
// }
// }
// // Check if we need to add the plugin and add it.
// if (addPlugin)
// {
// // Add the plugin.
// if (!qualityServicePluginAdded && TokenApplicationPlugin.IsMatch(line))
// {
// outputLines.Add(QualityServiceApplyPlugin);
// outputLines.AddRange(GenerateAppLovinPluginClosure(apiKey));
// qualityServicePluginAdded = true;
// }
// }
// }
// if ((addBuildScriptLines && (!qualityServiceRepositoryAdded || !qualityServiceDependencyClassPathAdded)) || (addPlugin && !qualityServicePluginAdded))
// {
// MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin. Quality Service Plugin Added?: " + qualityServicePluginAdded + ", Quality Service Repo added?: " + qualityServiceRepositoryAdded + ", Quality Service dependency added?: " + qualityServiceDependencyClassPathAdded);
// return null;
// }
// }
// return outputLines;
// }
// private static string GetFormattedBuildScriptLine(string buildScriptLine)
// {
// #if UNITY_2022_2_OR_NEWER
// return " "
// #elif UNITY_2019_3_OR_NEWER
// return " "
// #else
// return " "
// #endif
// + buildScriptLine;
// }
// private static IEnumerable GenerateAppLovinPluginClosure(string apiKey)
// {
// // applovin {
// // // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.
// // apiKey "456...a1b"
// // }
// var linesToInject = new List(5);
// linesToInject.Add("");
// linesToInject.Add("applovin {");
// linesToInject.Add(" // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.");
// linesToInject.Add(string.Format(QualityServiceApiKey, apiKey));
// linesToInject.Add("}");
// return linesToInject;
// }
// }
}
#endif