use std::path::PathBuf;

use garage_util::error::*;

pub const READ_KEY_ERROR: &str = "Unable to read node key. It will be generated by your garage node the first time is it launched. Ensure that your garage node is currently running. (The node key is supposed to be stored in your metadata directory.)";

pub fn node_id_command(config_file: PathBuf, quiet: bool) -> Result<(), Error> {
	let config = garage_util::config::read_config(config_file.clone()).err_context(format!(
		"Unable to read configuration file {}",
		config_file.to_string_lossy(),
	))?;

	let node_id =
		garage_rpc::system::read_node_id(&config.metadata_dir).err_context(READ_KEY_ERROR)?;

	let idstr = if let Some(addr) = config.rpc_public_addr {
		let idstr = format!("{}@{}", hex::encode(&node_id), addr);
		println!("{}", idstr);
		idstr
	} else {
		let idstr = hex::encode(&node_id);
		println!("{}", idstr);

		if !quiet {
			warn!("WARNING: I don't know the public address to reach this node.");
			warn!("In all of the instructions below, replace 127.0.0.1:{} by the appropriate address and port.", config.rpc_bind_addr.port());
		}

		format!("{}@127.0.0.1:{}", idstr, config.rpc_bind_addr.port())
	};

	if !quiet {
		eprintln!();
		eprintln!(
			"To instruct a node to connect to this node, run the following command on that node:"
		);
		eprintln!("    garage [-c <config file path>] node connect {}", idstr);
		eprintln!();
		eprintln!("Or instruct them to connect from here by running:");
		eprintln!(
			"    garage -c {} -h <remote node> node connect {}",
			config_file.to_string_lossy(),
			idstr
		);
		eprintln!(
			"where <remote_node> is their own node identifier in the format: <pubkey>@<ip>:<port>"
		);
		eprintln!();
		eprintln!("This node identifier can also be added as a bootstrap node in other node's garage.toml files:");
		eprintln!("    bootstrap_peers = [");
		eprintln!("        \"{}\",", idstr);
		eprintln!("        ...");
		eprintln!("    ]");
		eprintln!();
		eprintln!(
			r#"Security notice: Garage's intra-cluster communications are secured primarily by the shared
secret value rpc_secret.  However, an attacker that knows rpc_secret (for example if it
leaks) cannot connect if they do not know any of the identifiers of the nodes in the
cluster. It is thus a good security measure to try to keep them secret if possible.
				  "#
		);
	}

	Ok(())
}
