/*
 *  This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */

/*
This starts an sshd server used for accessing the project via an ssh gateway server

Ref.: https://nodejs.org/docs/latest-v16.x/api/child_process.html#optionsdetached
*/

import { spawn } from "node:child_process";
import { openSync } from "node:fs";
import { writeFile } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";

import { isEmpty } from "lodash";

import { getLogger } from "./logger";
import { SSH_LOG, SSH_ERR } from "./data";

const { info, warn } = getLogger("sshd");

// created by ./project-setup.ts
type EnvVars = { [key: string]: string };

export async function init(envVars?: EnvVars) {
  info("starting sshd");

  // SSHD does not inherit the environment variables.
  // We write a file for the user, which contains the custom variables.
  // Also, if there are no env variables define, we keep the comment and an otherwise empty file.
  try {
    const intro =
      "# This file is autogenerated!\n# Configure SSH environment variables via Project Settings → Custom environment variables.";
    const envData =
      envVars && !isEmpty(envVars)
        ? Object.entries(envVars)
            .map(([k, v]) => `${k.trim()}=${v}`) // no quotes around the value!
            .join("\n")
        : "";
    const envFn = join(homedir(), ".ssh", "environment");
    await writeFile(envFn, `${intro}\n${envData}\n`);
  } catch (err) {
    warn(`unable to write to ~/.ssh/environment -- ${err}`);
  }

  const out = openSync(SSH_LOG, "w");
  const err = openSync(SSH_ERR, "w");

  const sshd = spawn("bash", ["/cocalc/kucalc-start-sshd.sh"], {
    detached: true,
    stdio: ["ignore", out, err],
  });

  sshd.unref();
}
