#!/usr/bin/env bash
set -euo pipefail

echo "HarmonyOS release signing preflight"

node <<'NODE'
const fs = require('fs');

const buildProfilePath = 'build-profile.json5';
let buildProfile;
try {
  buildProfile = JSON.parse(fs.readFileSync(buildProfilePath, 'utf8'));
} catch (_error) {
  console.error(`${buildProfilePath} is missing or is not valid JSON.`);
  process.exit(1);
}

const signingConfigs = buildProfile?.app?.signingConfigs;
const containsPasswordField = (value) => {
  if (Array.isArray(value)) {
    return value.some(containsPasswordField);
  }
  if (!value || typeof value !== 'object') {
    return false;
  }

  return Object.entries(value).some(([key, child]) => {
    if ((key === 'storePassword' || key === 'keyPassword') && String(child || '').length > 0) {
      return true;
    }
    return containsPasswordField(child);
  });
};

if (!Array.isArray(signingConfigs) || signingConfigs.length > 0 || containsPasswordField(buildProfile)) {
  console.error(`${buildProfilePath} contains signing material.`);
  console.error('Restore the committed unsigned build profile before running a release.');
  process.exit(1);
}
NODE

if [[ ! -f "local.properties" ]]; then
  cat >&2 <<'EOF'
local.properties is missing.

Copy docs/release-signing.local.properties.example to local.properties and fill in
your HarmonyOS signing material before running make release.
EOF
  exit 1
fi

node <<'NODE'
const fs = require('fs');
const path = require('path');

const localPropertiesPath = 'local.properties';
const requiredKeys = [
  'biucing.harmony.signing.certpath',
  'biucing.harmony.signing.profile',
  'biucing.harmony.signing.storeFile',
  'biucing.harmony.signing.storePassword',
  'biucing.harmony.signing.keyAlias',
  'biucing.harmony.signing.keyPassword'
];
const fileKeys = [
  'biucing.harmony.signing.certpath',
  'biucing.harmony.signing.profile',
  'biucing.harmony.signing.storeFile'
];

function parseProperties(raw) {
  const values = {};
  for (const line of raw.split(/\r?\n/)) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) {
      continue;
    }
    const separator = trimmed.indexOf('=');
    if (separator < 0) {
      continue;
    }
    const key = trimmed.slice(0, separator).trim();
    const value = trimmed.slice(separator + 1).trim();
    values[key] = value;
  }
  return values;
}

const properties = parseProperties(fs.readFileSync(localPropertiesPath, 'utf8'));
const missing = requiredKeys.filter((key) => !properties[key]);
if (missing.length > 0) {
  console.error(`Missing signing key(s) in ${localPropertiesPath}:`);
  for (const key of missing) {
    console.error(`  - ${key}`);
  }
  process.exit(1);
}

for (const key of fileKeys) {
  const value = properties[key];
  const resolved = path.isAbsolute(value) ? value : path.resolve(value);
  if (!fs.existsSync(resolved)) {
    console.error(`Signing file for ${key} does not exist: ${value}`);
    process.exit(1);
  }
}

console.log('Release signing material is present and file paths resolve.');
NODE
