/*
 * 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 path from 'path';
import { getDefaultShell, getProjectType } from './utils';

export async function buildCjmpProject(): Promise<void> {
  const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;

  if (workspaceRoot) {
    console.log('The root directory of the workspace: ', workspaceRoot);
  } else {
    vscode.window.showErrorMessage('No folder or workspace is opened.');
    return;
  }

  const projectType = getProjectType();

  if (projectType === 'app') {
    await buildAppProject(workspaceRoot);
  } else if (projectType === 'logic-module' || projectType === 'module') {
    await buildLogicOrModuleProject(workspaceRoot);
  } else {
    return;
  }
}

function getTargetPlatformOptions(type: string): string[] | undefined {
  const platformMap = new Map<string, string[]>([

    ['apk', ['android-arm64']],
    ['hap', ['ohos-arm64']],
    ['ios', ['ios-arm64']],
    ['ipa', ['ios-arm64']],
    ['ios-sim', ['ios-sim-arm64']],

    ['aar', ['android-arm64']],
    ['har', ['ohos-arm64']],
    ['framework', ['ios-arm64']],
    ['framework-sim', ['ios-sim-arm64']]
  ]);

  return platformMap.get(type);
}

async function buildAppProject(workspaceRoot: string) {
  let targetPlatformOptions;
  const modeOptions = ['debug', 'release'];
  const types = process.platform === 'darwin' ? ['apk', 'hap', 'ios', 'ipa', 'ios-sim'] : ['apk', 'hap'];

  const type = await vscode.window.showQuickPick(types, {
    placeHolder: 'Select the app type',
  });

  if (!type) {
    vscode.window.showWarningMessage('Build canceled: No type selected.');
    return;
  }

  targetPlatformOptions = getTargetPlatformOptions(type);
  if (!targetPlatformOptions) {
    vscode.window.showWarningMessage('Build canceled: No platform options available.');
    return;
  }

  const targetPlatform = await vscode.window.showQuickPick(targetPlatformOptions, {
    placeHolder: 'Select the platform',
  });

  if (!targetPlatform) {
    vscode.window.showWarningMessage('Build canceled: No platform selected.');
    return;
  }

  const mode = await vscode.window.showQuickPick(modeOptions, {
    placeHolder: 'Select the build mode',
  });

  if (!mode) {
    vscode.window.showWarningMessage('Build canceled: No build mode selected.');
    return;
  }

  await cjmpBuildWithSpawn(workspaceRoot, type, targetPlatform, mode);
}

async function buildLogicOrModuleProject(workspaceRoot: string) {
  let targetPlatformOptions;
  const modeOptions = ['debug', 'release'];
  const types = process.platform === 'darwin' ? ['aar', 'har', 'framework', 'framework-sim'] : ['aar', 'har'];

  const type = await vscode.window.showQuickPick(types, {
    placeHolder: 'Select the package type',
  });

  if (!type) {
    vscode.window.showWarningMessage('Build canceled: No type selected.');
    return;
  }

  targetPlatformOptions = getTargetPlatformOptions(type);
  if (!targetPlatformOptions) {
    vscode.window.showWarningMessage('Build canceled: No platform options available.');
    return;
  }

  const targetPlatform = await vscode.window.showQuickPick(targetPlatformOptions, {
    placeHolder: 'Select the platform',
  });

  if (!targetPlatform) {
    vscode.window.showWarningMessage('Build canceled: No platform selected.');
    return;
  }

  const mode = await vscode.window.showQuickPick(modeOptions, {
    placeHolder: 'Select the build mode',
  });

  if (!mode) {
    vscode.window.showWarningMessage('Build canceled: No build mode selected.');
    return;
  }

  await cjmpBuildWithSpawn(workspaceRoot, type, targetPlatform, mode);
}

const cjmpBuildWithSpawn = async (localPath: string | undefined, type: string, target_platform: string, mode: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    try {
      const cjmpSdkPath = vscode.workspace.getConfiguration().get<string>('CJMP.sdkPath');
      if (!cjmpSdkPath) {
        vscode.window.showErrorMessage('CJMP SDK path is not configured in settings. Please set "CJMP.sdkPath" first.');
        reject(new Error('CJMP SDK path is not configured.'));
        return;
      }

      const isWindows = process.platform === 'win32';
      const shellPath = isWindows ? 'cmd.exe' : getDefaultShell();

      const buildCommand = `${path.join(cjmpSdkPath, 'keels')} build ${type} --platform ${target_platform} --${mode} -v`;

      const terminal = vscode.window.createTerminal({
        name: 'CJMP Build Terminal',
        shellPath: shellPath,
        cwd: localPath,
      });
      terminal.show();
      terminal.sendText(`${buildCommand}`);

    } catch (error) {
      vscode.window.showErrorMessage(`Error building ${type}. : ${error instanceof Error ? error.message : String(error)}`);
      reject(error);
    }
  });
};