import type { ForgeConfig } from '@electron-forge/shared-types';
import { MakerSquirrel } from '@electron-forge/maker-squirrel';
import { MakerZIP } from '@electron-forge/maker-zip';
import { MakerDeb } from '@electron-forge/maker-deb';
import { MakerRpm } from '@electron-forge/maker-rpm';
import { VitePlugin } from '@electron-forge/plugin-vite';
import { FusesPlugin } from '@electron-forge/plugin-fuses';
import { FuseV1Options, FuseVersion } from '@electron/fuses';

// Windows code signing via Azure Trusted Signing. Dormant unless the workflow
// provisions the dlib + metadata file and exports these env vars, so local
// `yarn make` and unsigned CI builds both work unchanged.
// @electron/windows-sign prepends `sign /tr <timestampServer> /td sha256 /fd sha256`
// to the sha256 pass, so `signWithParams` only carries the Azure Trusted Signing
// bits. Skip the sha1 pass (deprecated; not supported by Trusted Signing).
const windowsSign = process.env.AZURE_METADATA_JSON_PATH ? {
  debug: true,
  signToolPath: process.env.SIGNTOOL_PATH,
  hashes: ['sha256'] as any, // eslint-disable-line @typescript-eslint/no-explicit-any
  timestampServer: 'http://timestamp.acs.microsoft.com',
  signWithParams: [
    '/v',
    '/dlib', process.env.AZURE_DLIB_PATH,
    '/dmdf', process.env.AZURE_METADATA_JSON_PATH,
  ].join(' '),
} : undefined;

const config: ForgeConfig = {
  packagerConfig: {
    asar: true,
    icon: './assets/flowy',
    appBundleId: 'live.flowy.llink',
    protocols: [
      { name: 'llink', schemes: ['llink'] },
    ],
    extendInfo: {
      NSMicrophoneUsageDescription: 'llink needs microphone access to record audio messages.',
      NSCameraUsageDescription: 'llink needs camera access to record video messages.',
    },
    osxSign: {},
    osxNotarize: {
      keychainProfile: 'default',
    },
    windowsSign
  },
  publishers: [
    {
      name: '@electron-forge/publisher-gcs',
      config: {
        storageOptions: {
          projectId: 'flowy-prod-440017'
        },
        bucket: 'flowy-releases',
        folder: 'llink',
        // NOTE: commented out because we do not want to apply per object ACL which conflicts with uniform bucket-level access that's already public
        // public: true
      }
    }
  ],
  rebuildConfig: {},
  makers: [
    new MakerSquirrel((arch) => ({
      remoteReleases: `https://storage.googleapis.com/flowy-releases/llink/win32/${arch}`,
      setupIcon: './assets/flowy.ico',
      iconUrl: 'https://storage.googleapis.com/flowy-releases/llink/win32/x64/flowy.ico',
      windowsSign
    })),
    new MakerZIP((arch) => ({
      macUpdateManifestBaseUrl: `https://storage.googleapis.com/flowy-releases/llink/darwin/${arch}`
    }), ['darwin']),
    new MakerRpm({}),
    new MakerDeb({}),
  ],
  plugins: [
    new VitePlugin({
      // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
      // If you are familiar with Vite configuration, it will look really familiar.
      build: [
        {
          // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
          entry: 'src/main.ts',
          config: 'vite.main.config.ts',
          target: 'main',
        },
        {
          entry: 'src/preload.ts',
          config: 'vite.preload.config.ts',
          target: 'preload',
        },
      ],
      renderer: [
        {
          name: 'main_window',
          config: 'vite.renderer.config.mts',
        },
        {
          name: 'autoplay_window',
          config: 'vite.autoplay.config.mts',
        },
        {
          name: 'huddle_window',
          config: 'vite.huddle.config.mts',
        },
        {
          name: 'screen_record_window',
          config: 'vite.screen-record.config.mts',
        },
      ],
    }),
    // Fuses are used to enable/disable various Electron functionality
    // at package time, before code signing the application
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};

export default config;
