/*

 * Copyright (c) 2025 Huawei Device Co., Ltd.

 * Licensed 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 * as vscode from 'vscode';

import * as cp from 'child_process';
import { resolveKeelsCommand } from './cjmpSdk';
import { getCjmpEmulatorsOutputChannel } from './cjmpOutputChannel';


export interface Emulator {

  id: string;

  name: string;

  platform: string;

}



export async function LaunchEmulator(context: vscode.ExtensionContext): Promise<void> {

  try {

    const emulators = await listEmulators();



    if (emulators.length === 0) {

      vscode.window.showWarningMessage('No available simulators found.');
      return;

    }

    const selected = await vscode.window.showQuickPick(

      emulators.map(emu => ({

         label: `${emu.name} (${emu.id}, ${emu.platform})`,

         emulator: emu

      })),

      { placeHolder: 'Select a simulator to launch.' }
    );



    if (!selected) {

      return;

    }



    await launchSelectedEmulator(selected.emulator.id);

  } catch (error) {

    vscode.window.showErrorMessage(`Failed to start simulator: ${error}`);
  }

}



export async function listEmulators(): Promise<Emulator[]> {
  return new Promise((resolve, reject) => {

    const keelsCommand = resolveKeelsCommand();
    if (!keelsCommand) {
      resolve([]);
      return;
    }
    const outputChannel = getCjmpEmulatorsOutputChannel();
    outputChannel.appendLine('');
    outputChannel.appendLine('=== CJMP Emulators ===');
    const command = `${keelsCommand.executablePath} emulators --list`;
    outputChannel.appendLine(`> ${command}`);
    let fullOutput = '';
    const process = cp.spawn(command, [], {
      shell: true,
      env: keelsCommand.environment,
    });


    process.stdout.on('data', (data) => {

      const output = data.toString();

      outputChannel.append(output);

      fullOutput += output;

    });

    process.stderr.on('data', (data) => {

      const errorOutput = data.toString();

      outputChannel.append(errorOutput);

      fullOutput += errorOutput;

    });



    process.on('close', (code) => {

      const parsed = parseEmulatorsOutput(fullOutput);



      if (parsed.length > 0) {

        resolve(parsed);

      } else {

        resolve([]);

      }

    });

  });

}



export async function launchSelectedEmulator(emulatorId: string): Promise<void> {
  const keelsCommand = resolveKeelsCommand();
  if (!keelsCommand) {
    return;
  }
  const command = `${keelsCommand.executablePath} emulators --launch ${emulatorId}`;
  const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;

  const terminal = vscode.window.createTerminal({

    name: 'CJMP Emulators Terminal',
    cwd: workspaceRoot,
    env: keelsCommand.environment,
  });
  terminal.sendText(command);

  terminal.show();

  return Promise.resolve();

}



function parseEmulatorsOutput(output: string): Emulator[] {

  const emulators: Emulator[] = [];

  const lines = output.split('\n');

  let foundTableStart = false;

  for (const line of lines) {

    const trimmedLine = line.trim();



    if (!trimmedLine || trimmedLine.includes('To run an emulator')) {

      continue;

    }

    if (trimmedLine.includes('---')) {

      foundTableStart = true;

      continue;

    }

    if (!foundTableStart) {

      continue;

    }



    const parts = trimmedLine.split(/\s{2,}/).filter(part => part.trim());

    if (parts.length >= 3) {

      // Handle platform-specific bullet encoding: Windows '\\u2022' vs macOS '\u2022'

      const id = parts[0].replace(/^(\\u2022|\u2022)\s*/, '').trim();

      const name = parts[1].replace(/^(\\u2022|\u2022)\s*/, '').trim();

      const platform = parts[2].replace(/^(\\u2022|\u2022)\s*/, '').trim();



      emulators.push({

        id: id,

        name: name,

        platform: platform

      });

    }

  }

  return emulators;

}