/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import assert from 'node:assert/strict';
import childProcess from 'node:child_process';
import { EventEmitter } from 'node:events';
import { syncBuiltinESMExports } from 'node:module';
import { dirname, join } from 'node:path';
import { lstat, mkdir, mkdtemp, readdir, readFile, rm, symlink, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import test from 'node:test';
import { buildCli, rustTarget, stageDesktopApp, stageDesktopBundle } from './build-cli.mjs';

const manifest =
  '{"id":"org.example.maka","name":"Maka & Co","version":"1.2.3-beta.1","entry":"main.js"}';

// A PNG signature and IHDR are all the icon staging reads.
function logo(size = 1024) {
  const png = Buffer.alloc(33);
  Buffer.from('\x89PNG\r\n\x1a\n', 'latin1').copy(png);
  png.writeUInt32BE(13, 8);
  png.write('IHDR', 12, 'latin1');
  png.writeUInt32BE(size, 16);
  png.writeUInt32BE(size, 20);
  return png;
}

async function repository(root) {
  const app = join(root, 'products/maka/desktop-shell/app');
  await mkdir(join(app, 'icons'), { recursive: true });
  await writeFile(join(app, 'gpui-shell.json'), manifest);
  await writeFile(join(app, 'main.js'), 'authored application');
  await writeFile(join(app, 'icons/logo.svg'), '<svg/>');
  await mkdir(join(root, 'assets'), { recursive: true });
  await writeFile(join(root, 'assets/logo.png'), logo());
}

test('CLI builds use the requested target and artifact path', async (t) => {
  const root = await mkdtemp(join(tmpdir(), 'maka-build-cli-'));
  t.after(() => rm(root, { recursive: true, force: true }));
  const sourceRoot = join(root, 'extracted-source');
  for (const directory of [root, sourceRoot]) await repository(directory);
  const previous = process.env.CARGO_TARGET_DIR;
  process.env.CARGO_TARGET_DIR = 'target/isolated release';
  let invocation;
  let exitCode = 0;
  t.mock.method(childProcess, 'spawn', (command, args, options) => {
    invocation = { command, args, options };
    const child = new EventEmitter();
    queueMicrotask(() => child.emit('exit', exitCode, null));
    return child;
  });
  syncBuiltinESMExports();
  t.after(() => {
    t.mock.restoreAll();
    syncBuiltinESMExports();
    if (previous === undefined) delete process.env.CARGO_TARGET_DIR;
    else process.env.CARGO_TARGET_DIR = previous;
  });
  for (const target of [
    undefined,
    'x86_64-unknown-linux-gnu',
    'aarch64-unknown-linux-gnu',
    'aarch64-apple-darwin',
    'x86_64-pc-windows-msvc',
  ]) {
    const triple = target ?? rustTarget();
    const linux = triple.includes('-linux-');
    const directory = join(root, process.env.CARGO_TARGET_DIR);
    const binaryDirectory = join(directory, ...(linux || target ? [triple] : []), 'release');
    const macos = triple.includes('-apple-darwin');
    const app = macos ? 'Maka.app/Contents/Resources/app' : 'app';
    for (const directory of new Set([app, 'app'])) {
      await mkdir(join(binaryDirectory, directory), { recursive: true });
      await writeFile(join(binaryDirectory, directory, 'obsolete.js'), 'removed module');
    }
    await writeFile(join(binaryDirectory, 'maka-desktop-shell'), 'shell bytes');
    const output = await buildCli({ release: true, target, repositoryRoot: root });
    await assert.rejects(lstat(join(dirname(output), app, 'obsolete.js')), { code: 'ENOENT' });
    assert.equal(
      await readFile(join(dirname(output), app, 'main.js'), 'utf8'),
      'authored application',
    );
    assert.equal(await readFile(join(dirname(output), app, 'icons/logo.svg'), 'utf8'), '<svg/>');
    if (macos) {
      const contents = join(dirname(output), 'Maka.app/Contents');
      assert.equal(
        await readFile(join(contents, 'MacOS/maka-desktop-shell'), 'utf8'),
        'shell bytes',
      );
      if (process.platform !== 'win32')
        assert.equal((await lstat(join(contents, 'MacOS/maka-desktop-shell'))).mode & 0o777, 0o755);
      const plist = await readFile(join(contents, 'Info.plist'), 'utf8');
      for (const [key, value] of [
        ['CFBundleDisplayName', 'Maka &amp; Co'],
        ['CFBundleExecutable', 'maka-desktop-shell'],
        ['CFBundleIconFile', 'Maka'],
        ['CFBundleIdentifier', 'org.example.maka'],
        ['CFBundleName', 'Maka &amp; Co'],
        ['CFBundleShortVersionString', '1.2.3-beta.1'],
        ['CFBundleVersion', '1.2.3'],
      ])
        assert.ok(plist.includes(`<key>${key}</key>\n  <string>${value}</string>`), key);
      if (process.platform === 'darwin')
        childProcess.execFileSync('plutil', ['-lint', join(contents, 'Info.plist')]);
      const icon = await readFile(join(contents, 'Resources/Maka.icns'));
      assert.equal(icon.toString('latin1', 0, 4), 'icns');
      assert.equal(icon.readUInt32BE(4), icon.length);
      assert.equal(icon.toString('latin1', 8, 12), 'ic10');
      assert.equal(icon.readUInt32BE(12), icon.length - 8);
      assert.deepEqual(icon.subarray(16), logo());
      await assert.rejects(lstat(join(dirname(output), 'app')), { code: 'ENOENT' });
    }
    assert.equal(invocation.command, 'cargo');
    assert.equal(invocation.options.cwd, root);
    assert.deepEqual(invocation.args, [
      linux ? 'zigbuild' : 'build',
      '--locked',
      '-p',
      'maka-cli',
      '-p',
      'maka-desktop-shell',
      '-p',
      'maka-python-runtime',
      '--target-dir',
      directory,
      '--release',
      ...(linux ? ['--target', triple + '.2.28'] : target ? ['--target', target] : []),
    ]);
    assert.equal(
      output,
      join(
        directory,
        ...(linux || target ? [triple] : []),
        'release',
        triple.includes('-windows-') ? 'maka.exe' : 'maka',
      ),
    );
  }
  await mkdir(join(root, 'target/debug'), { recursive: true });
  await writeFile(join(root, 'target/debug/maka-desktop-shell'), 'shell bytes');
  assert.equal(
    await buildCli({ repositoryRoot: root }),
    join(root, 'target/debug', process.platform === 'win32' ? 'maka.exe' : 'maka'),
  );
  assert.deepEqual(invocation.args, [
    'build',
    '--locked',
    '-p',
    'maka-cli',
    '-p',
    'maka-desktop-shell',
    '-p',
    'maka-python-runtime',
    '--target-dir',
    join(root, 'target'),
  ]);
  const sourceEnv = { MAKA_JS_DEPS: sourceRoot };
  await mkdir(join(sourceRoot, 'target/aarch64-apple-darwin/release'), { recursive: true });
  await writeFile(
    join(sourceRoot, 'target/aarch64-apple-darwin/release/maka-desktop-shell'),
    'shell bytes',
  );
  assert.equal(
    await buildCli({
      release: true,
      target: 'aarch64-apple-darwin',
      repositoryRoot: sourceRoot,
      env: sourceEnv,
    }),
    join(sourceRoot, 'target/aarch64-apple-darwin/release/maka'),
  );
  assert.equal(invocation.options.cwd, sourceRoot);
  assert.equal(invocation.options.env, sourceEnv);
  exitCode = 1;
  await assert.rejects(buildCli({ release: true, repositoryRoot: root }), /Maka build failed: 1/u);
});

test('desktop app staging rejects symlinks without replacing the accepted sidecar', async () => {
  const root = await mkdtemp(join(tmpdir(), 'maka-app-staging-'));
  try {
    const source = join(root, 'products/maka/desktop-shell/app');
    const destination = join(root, 'bin/app');
    await mkdir(source, { recursive: true });
    await writeFile(join(source, 'gpui-shell.json'), '{"entry":"main.js"}');
    await writeFile(join(source, 'main.js'), 'original app');
    await stageDesktopApp(root, destination);
    await writeFile(join(root, 'outside.js'), 'not authored app content');
    await symlink(root, join(source, 'linked'), process.platform === 'win32' ? 'junction' : 'dir');
    await assert.rejects(stageDesktopApp(root, destination), /non-regular file/);
    assert.equal(await readFile(join(destination, 'main.js'), 'utf8'), 'original app');
    await assert.rejects(lstat(join(destination, 'linked')), { code: 'ENOENT' });
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});

test('a failed bundle staging keeps the previous Maka.app', async () => {
  const root = await mkdtemp(join(tmpdir(), 'maka-bundle-staging-'));
  try {
    await repository(root);
    const shell = join(root, 'maka-desktop-shell');
    await writeFile(shell, 'original shell');
    const destination = join(root, 'bin/Maka.app');
    await mkdir(dirname(destination));
    await stageDesktopBundle(root, shell, destination);
    await writeFile(shell, 'replacement shell');
    const app = join(root, 'products/maka/desktop-shell/app');
    await symlink(root, join(app, 'linked'), process.platform === 'win32' ? 'junction' : 'dir');
    await assert.rejects(stageDesktopBundle(root, shell, destination), /non-regular file/);
    await rm(join(app, 'linked'));
    await writeFile(join(root, 'assets/logo.png'), logo(512));
    await assert.rejects(stageDesktopBundle(root, shell, destination), /1024x1024 PNG/);
    await writeFile(join(root, 'assets/logo.png'), logo());
    await writeFile(join(app, 'gpui-shell.json'), '{"entry":"main.js"}');
    await assert.rejects(stageDesktopBundle(root, shell, destination), /has no id/);
    assert.equal(
      await readFile(join(destination, 'Contents/MacOS/maka-desktop-shell'), 'utf8'),
      'original shell',
    );
    assert.deepEqual(await readdir(dirname(destination)), ['Maka.app']);
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});
