package minhhai2209.jirapluginconverter.plugin.lifecycle;

import org.apache.http.HttpHeaders;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import com.atlassian.event.api.EventPublisher;
import com.atlassian.oauth.consumer.ConsumerService;
import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.event.PluginEventListener;
import com.atlassian.plugin.event.events.PluginDisabledEvent;
import com.atlassian.plugin.event.events.PluginEnabledEvent;
import com.atlassian.plugin.event.events.PluginUninstalledEvent;
import com.atlassian.sal.api.ApplicationProperties;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.sal.api.transaction.TransactionTemplate;
import com.atlassian.upm.api.license.PluginLicenseManager;

import minhhai2209.jirapluginconverter.plugin.jwt.JwtComposer;
import minhhai2209.jirapluginconverter.plugin.setting.KeyUtils;
import minhhai2209.jirapluginconverter.plugin.setting.LifeCycleUtils;
import minhhai2209.jirapluginconverter.plugin.setting.PluginSetting;
import minhhai2209.jirapluginconverter.plugin.setting.SenUtils;
import minhhai2209.jirapluginconverter.plugin.utils.HttpClientFactory;
import minhhai2209.jirapluginconverter.utils.ExceptionUtils;
import minhhai2209.jirapluginconverter.utils.JsonUtils;

public class PluginLifeCycleEventListener implements InitializingBean, DisposableBean {

  private EventPublisher eventPublisher;

  private PluginSettingsFactory pluginSettingsFactory;

  private TransactionTemplate transactionTemplate;

  private ApplicationProperties applicationProperties;

  private PluginLicenseManager pluginLicenseManager;

  private ConsumerService consumerService;

  public PluginLifeCycleEventListener(
      EventPublisher eventPublisher,
      PluginSettingsFactory pluginSettingsFactory,
      TransactionTemplate transactionTemplate,
      ApplicationProperties applicationProperties,
      PluginLicenseManager pluginLicenseManager,
      ConsumerService consumerService) {

    this.eventPublisher = eventPublisher;
    this.pluginSettingsFactory = pluginSettingsFactory;
    this.transactionTemplate = transactionTemplate;
    this.applicationProperties = applicationProperties;
    this.pluginLicenseManager = pluginLicenseManager;
    this.consumerService = consumerService;
  }

  @Override
  public void destroy() throws Exception {
    eventPublisher.unregister(this);
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    eventPublisher.register(this);
  }

  @PluginEventListener
  public void onPluginEnabled(PluginEnabledEvent event) throws Exception {
    Plugin plugin = event.getPlugin();
    String pluginKey = plugin.getKey();
    if (PluginSetting.PLUGIN_KEY.equals(pluginKey)) {
      String sharedSecret = KeyUtils.getSharedSecret();
      String uri;
      EventType eventType;
      if (sharedSecret == null) {
        eventType = EventType.installed;
        uri = LifeCycleUtils.getInstalledUri();
      } else {
        eventType = EventType.enabled;
        uri = LifeCycleUtils.getEnabledUri();
      }
      PluginSetting.load(pluginSettingsFactory, transactionTemplate, pluginLicenseManager, consumerService);
      notify(eventType, uri, plugin);
    }
  }

  @PluginEventListener
  public void onPluginDisabled(PluginDisabledEvent event) throws Exception {
    Plugin plugin = event.getPlugin();
    String pluginKey = plugin.getKey();
    if (PluginSetting.PLUGIN_KEY.equals(pluginKey)) {
      String uri = LifeCycleUtils.getDisabledUri();
      notify(EventType.disabled, uri, plugin);
    }
  }

  @PluginEventListener
  public void onPluginUninstalled(PluginUninstalledEvent event) throws Exception {
    Plugin plugin = event.getPlugin();
    String pluginKey = plugin.getKey();
    if (PluginSetting.PLUGIN_KEY.equals(pluginKey)) {
      KeyUtils.deleteSharedSecret(pluginSettingsFactory, transactionTemplate);
      String uri = LifeCycleUtils.getUninstalledUri();
      notify(EventType.uninstalled, uri, plugin);
    }
  }

  private void notify(EventType eventType, String uri, Plugin plugin) throws Exception {

    if (uri != null) {

      PluginLifeCycleEvent event = new PluginLifeCycleEvent();
      event.setBaseUrl(PluginSetting.getJiraBaseUrl());
      event.setClientKey(KeyUtils.getClientKey());
      event.setDescription("");
      event.setEventType(eventType);
      event.setKey(PluginSetting.PLUGIN_KEY);
      event.setPluginsVersion(plugin.getPluginInformation().getVersion());
      event.setProductType(ProductType.jira);
      event.setPublicKey(KeyUtils.getPublicKey());
      event.setServerVersion(applicationProperties.getVersion());
      event.setServiceEntitlementNumber(SenUtils.getSen());
      event.setSharedSecret(KeyUtils.getSharedSecret());

      notify(uri, event);
    }
  }

  private void notify(String uri, PluginLifeCycleEvent event) {
    try {
      String url = getUrl(uri);
      HttpClient httpClient = HttpClientFactory.build();
      HttpPost post = new HttpPost(url);
      String json = JsonUtils.toJson(event);
      post.setEntity(new StringEntity(json));
      post.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
      String jwt = JwtComposer.compose(KeyUtils.getClientKey(), KeyUtils.getSharedSecret(), "POST", uri, null, null);
      post.addHeader("Authorization", "JWT " + jwt);
      httpClient.execute(post);
    } catch (Exception e) {
      ExceptionUtils.throwUnchecked(e);
    }
  }

  private static String getUrl(String uri) {
    return uri == null ? null : PluginSetting.getPluginBaseUrl() + uri;
  }
}

@@ -2982,24 +2982,133 @@
 edSecret();%0A
+      PluginSetting.load(pluginSettingsFactory, transactionTemplate, pluginLicenseManager, consumerService);%0A
       String
@@ -3375,117 +3375,8 @@
   %7D%0A
-      PluginSetting.load(pluginSettingsFactory, transactionTemplate, pluginLicenseManager, consumerService);%0A
     

support all life cycle events