#include "config.h"
#include <bitcoin/feerate.h>
#include <bitcoin/script.h>
#include <ccan/cast/cast.h>
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <channeld/channeld_wiregen.h>
#include <closingd/closingd_wiregen.h>
#include <common/close_tx.h>
#include <common/closing_fee.h>
#include <common/configdir.h>
#include <common/fee_states.h>
#include <common/initial_commit_tx.h>
#include <common/json_command.h>
#include <common/json_param.h>
#include <common/shutdown_scriptpubkey.h>
#include <common/timeout.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <connectd/connectd_wiregen.h>
#include <errno.h>
#include <gossipd/gossipd_wiregen.h>
#include <hsmd/capabilities.h>
#include <inttypes.h>
#include <lightningd/bitcoind.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel.h>
#include <lightningd/closing_control.h>
#include <lightningd/dual_open_control.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/opening_common.h>
#include <lightningd/options.h>
#include <lightningd/peer_control.h>
#include <lightningd/peer_fd.h>
#include <lightningd/subd.h>
#include <openingd/dualopend_wiregen.h>
#include <wally_bip32.h>

struct close_command {
	/* Inside struct lightningd close_commands. */
	struct list_node list;
	/* Command structure. This is the parent of the close command. */
	struct command *cmd;
	/* Channel being closed. */
	struct channel *channel;

};

/* Resolve a single close command. */
static void
resolve_one_close_command(struct close_command *cc, bool cooperative)
{
	struct json_stream *result = json_stream_success(cc->cmd);

	json_add_tx(result, "tx", cc->channel->last_tx);
	if (!invalid_last_tx(cc->channel->last_tx)) {
		struct bitcoin_txid txid;
		bitcoin_txid(cc->channel->last_tx, &txid);
		json_add_txid(result, "txid", &txid);
	}
	if (cooperative)
		json_add_string(result, "type", "mutual");
	else
		json_add_string(result, "type", "unilateral");

	was_pending(command_success(cc->cmd, result));
}

/* Resolve a close command for a channel that will be closed soon: returns
 * the cmd_id of one, if any (allocated off ctx). */
const char *resolve_close_command(const tal_t *ctx,
				  struct lightningd *ld, struct channel *channel,
				  bool cooperative)
{
	struct close_command *cc;
	struct close_command *n;
	const char *cmd_id = NULL;

	list_for_each_safe(&ld->close_commands, cc, n, list) {
		if (cc->channel != channel)
			continue;
		if (!cmd_id)
			cmd_id = tal_strdup(ctx, cc->cmd->id);
		resolve_one_close_command(cc, cooperative);
	}
	return cmd_id;
}

/* Destroy the close command structure in reaction to the
 * channel being destroyed. */
static void
destroy_close_command_on_channel_destroy(struct channel *_ UNUSED,
					 struct close_command *cc)
{
	/* The cc has the command as parent, so resolving the
	 * command destroys the cc and triggers destroy_close_command.
	 * Clear the cc->channel first so that we will not try to
	 * remove a destructor. */
	cc->channel = NULL;
	was_pending(command_fail(cc->cmd, LIGHTNINGD,
				 "Channel forgotten before proper close."));
}

/* Destroy the close command structure. */
static void
destroy_close_command(struct close_command *cc)
{
	list_del(&cc->list);
	/* If destroy_close_command_on_channel_destroy was
	 * triggered beforehand, it will have cleared
	 * the channel field, preventing us from removing it
	 * from an already-destroyed channel. */
	if (!cc->channel)
		return;
	tal_del_destructor2(cc->channel,
			    &destroy_close_command_on_channel_destroy,
			    cc);
}

/* Handle timeout. */
static void
close_command_timeout(struct close_command *cc)
{
	/* This will trigger drop_to_chain, which will trigger
	 * resolution of the command and destruction of the
	 * close_command. */
	json_notify_fmt(cc->cmd, LOG_INFORM,
			"Timed out, forcing close.");
	channel_fail_permanent(cc->channel, REASON_USER,
			       "Forcibly closed by `close` command timeout");
}

/* Construct a close command structure and add to ld. */
static void
register_close_command(struct lightningd *ld,
		       struct command *cmd,
		       struct channel *channel,
		       unsigned int timeout)
{
	struct close_command *cc;
	assert(channel);

	cc = tal(cmd, struct close_command);
	list_add_tail(&ld->close_commands, &cc->list);
	cc->cmd = cmd;
	cc->channel = channel;
	tal_add_destructor(cc, &destroy_close_command);
	tal_add_destructor2(channel,
			    &destroy_close_command_on_channel_destroy,
			    cc);

	if (!channel->owner) {
		char *msg = tal_strdup(tmpctx, "peer is offline, will negotiate once they reconnect");
		if (timeout)
			tal_append_fmt(&msg, " (%u seconds before unilateral close)",
				       timeout);
		json_notify_fmt(cmd, LOG_INFORM, "%s.", msg);
	}
	log_debug(ld->log, "close_command: timeout = %u", timeout);
	if (timeout)
		new_reltimer(ld->timers, cc, time_from_sec(timeout),
			     &close_command_timeout, cc);
}

static struct amount_sat calc_tx_fee(struct amount_sat sat_in,
				     const struct bitcoin_tx *tx)
{
	struct amount_asset amt;
	struct amount_sat fee = sat_in;
	const u8 *oscript;
	size_t scriptlen;
	for (size_t i = 0; i < tx->wtx->num_outputs; i++) {
		amt = bitcoin_tx_output_get_amount(tx, i);
		oscript = bitcoin_tx_output_get_script(NULL, tx, i);
		scriptlen = tal_bytelen(oscript);
		tal_free(oscript);

		if (chainparams->is_elements && scriptlen == 0)
			continue;

		/* Ignore outputs that are not denominated in our main
		 * currency. */
		if (!amount_asset_is_main(&amt))
			continue;

		if (!amount_sat_sub(&fee, fee, amount_asset_to_sat(&amt)))
			fatal("Tx spends more than input %s? %s",
			      type_to_string(tmpctx, struct amount_sat, &sat_in),
			      type_to_string(tmpctx, struct bitcoin_tx, tx));
	}
	return fee;
}

/* Assess whether a proposed closing fee is acceptable. */
static bool closing_fee_is_acceptable(struct lightningd *ld,
				      struct channel *channel,
				      const struct bitcoin_tx *tx)
{
	struct amount_sat fee, last_fee, min_fee;
	u64 weight;
	u32 min_feerate;
	bool feerate_unknown;

	/* Calculate actual fee (adds in eliminated outputs) */
	fee = calc_tx_fee(channel->funding_sats, tx);
	last_fee = calc_tx_fee(channel->funding_sats, channel->last_tx);

	/* Weight once we add in sigs. */
	assert(!tx->wtx->inputs[0].witness
	       || tx->wtx->inputs[0].witness->num_items == 0);
	weight = bitcoin_tx_weight(tx) + bitcoin_tx_2of2_input_witness_weight();

	log_debug(channel->log, "Their actual closing tx fee is %s"
		 " vs previous %s: weight is %"PRIu64,
		  type_to_string(tmpctx, struct amount_sat, &fee),
		  type_to_string(tmpctx, struct amount_sat, &last_fee),
		  weight);

	/* If we don't have a feerate estimate, this gives feerate_floor */
	min_feerate = feerate_min(ld, &feerate_unknown);

	min_fee = amount_tx_fee(min_feerate, weight);
	if (amount_sat_less(fee, min_fee)) {
		log_debug(channel->log, "... That's below our min %s"
			  " for weight %"PRIu64" at feerate %u",
			  type_to_string(tmpctx, struct amount_sat, &min_fee),
			  weight, min_feerate);
		return false;
	}

	/* Prefer new over old: this covers the preference
	 * for a mutual close over a unilateral one. */

	return true;
}

static void peer_received_closing_signature(struct channel *channel,
					    const u8 *msg)
{
	struct bitcoin_signature sig;
	struct bitcoin_tx *tx;
	struct bitcoin_txid tx_id;
	struct lightningd *ld = channel->peer->ld;
	u8 *funding_wscript;

	if (!fromwire_closingd_received_signature(msg, msg, &sig, &tx)) {
		channel_internal_error(channel,
				       "Bad closing_received_signature %s",
				       tal_hex(msg, msg));
		return;
	}
	tx->chainparams = chainparams;

	funding_wscript = bitcoin_redeem_2of2(tmpctx,
				       	      &channel->local_funding_pubkey,
				       	      &channel->channel_info.remote_fundingkey);
	if (!check_tx_sig(tx, 0, NULL, funding_wscript,
			  &channel->channel_info.remote_fundingkey, &sig)) {
		channel_internal_error(channel,
				       "Bad closing_received_signature %s",
				       tal_hex(msg, msg));
		return;
	}

	if (closing_fee_is_acceptable(ld, channel, tx)) {
		channel_set_last_tx(channel, tx, &sig);
		wallet_channel_save(ld->wallet, channel);
	}


	// Send back the txid so we can update the billboard on selection.
	bitcoin_txid(channel->last_tx, &tx_id);
	/* OK, you can continue now. */
	subd_send_msg(channel->owner,
		      take(towire_closingd_received_signature_reply(channel, &tx_id)));
}

static void peer_closing_complete(struct channel *channel, const u8 *msg)
{
	if (!fromwire_closingd_complete(msg)) {
		channel_internal_error(channel, "Bad closing_complete %s",
				       tal_hex(msg, msg));
		return;
	}

	/* Don't report spurious failure when closingd exits. */
	channel_set_owner(channel, NULL);
	/* Clear any transient negotiation messages */
	channel_set_billboard(channel, false, NULL);

	/* Retransmission only, ignore closing. */
	if (channel_closed(channel))
		return;

	/* Channel gets dropped to chain cooperatively. */
	drop_to_chain(channel->peer->ld, channel, true);
	channel_set_state(channel,
			  CLOSINGD_SIGEXCHANGE,
			  CLOSINGD_COMPLETE,
			  REASON_UNKNOWN,
			  "Closing complete");
}

static void peer_closing_notify(struct channel *channel, const u8 *msg)
{
	char *message;
	struct close_command *i;
	enum log_level level;

	if (!fromwire_closingd_notification(msg, msg, &level, &message)) {
		channel_internal_error(channel, "Bad closing_notify %s",
				       tal_hex(msg, msg));
		return;
	}

	list_for_each(&channel->peer->ld->close_commands, i, list) {
		if (i->channel != channel)
			continue;
		json_notify_fmt(i->cmd, level, "%s", message);
	}
}

static unsigned closing_msg(struct subd *sd, const u8 *msg, const int *fds UNUSED)
{
	enum closingd_wire t = fromwire_peektype(msg);

	switch (t) {
	case WIRE_CLOSINGD_RECEIVED_SIGNATURE:
		peer_received_closing_signature(sd->channel, msg);
		break;

	case WIRE_CLOSINGD_COMPLETE:
		peer_closing_complete(sd->channel, msg);
		break;

	case WIRE_CLOSINGD_NOTIFICATION:
		peer_closing_notify(sd->channel, msg);
		break;

	/* We send these, not receive them */
	case WIRE_CLOSINGD_INIT:
	case WIRE_CLOSINGD_RECEIVED_SIGNATURE_REPLY:
		break;
	}

	return 0;
}

void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
{
	u8 *initmsg;
	u32 min_feerate, feerate, *max_feerate;
	struct amount_msat their_msat;
	struct amount_sat feelimit;
	int hsmfd;
	struct lightningd *ld = channel->peer->ld;
	u32 final_commit_feerate;
	bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
	bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);

	if (!channel->shutdown_scriptpubkey[REMOTE]) {
		channel_internal_error(channel,
				       "Can't start closing: no remote info");
		return;
	}

	hsmfd = hsm_get_client_fd(ld, &channel->peer->id, channel->dbid,
				  HSM_CAP_SIGN_CLOSING_TX
				  | HSM_CAP_COMMITMENT_POINT);

	channel_set_owner(channel,
			  new_channel_subd(channel, ld,
					   "lightning_closingd",
					   channel, &channel->peer->id,
					   channel->log, true,
					   closingd_wire_name, closing_msg,
					   channel_errmsg,
					   channel_set_billboard,
					   take(&peer_fd->fd),
					   take(&hsmfd),
					   NULL));

	if (!channel->owner) {
		log_broken(channel->log, "Could not subdaemon closing: %s",
			    strerror(errno));
		/* Disconnect it. */
		subd_send_msg(ld->connectd,
			      take(towire_connectd_discard_peer(NULL, &channel->peer->id,
								channel->peer->connectd_counter)));
		return;
	}

	/* FIXME: This is the old BOLT 2 text, which restricted the closing
	 * fee to cap at the final commitment fee.  We still do this for now.
	 *
	 * The sending node:
	 *  - MUST set `fee_satoshis` less than or equal to the base
	 *    fee of the final commitment transaction, as calculated in
	 *    [BOLT #3](03-transactions.md#fee-calculation).
	 */
	final_commit_feerate = get_feerate(channel->fee_states,
					   channel->opener, LOCAL);
	feelimit = commit_tx_base_fee(final_commit_feerate, 0,
				      option_anchor_outputs,
				      option_anchors_zero_fee_htlc_tx);

	/* If we can't determine feerate, start at half unilateral feerate. */
	feerate = mutual_close_feerate(ld->topology);
	if (!feerate) {
		feerate = final_commit_feerate / 2;
		if (feerate < get_feerate_floor(ld->topology))
			feerate = get_feerate_floor(ld->topology);
	}

	/* We use a feerate if anchor_outputs, otherwise max fee is set by
	 * the final unilateral. */
	if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
		max_feerate = tal(tmpctx, u32);
		/* Aim for reasonable max, but use final if we don't know. */
		*max_feerate = unilateral_feerate(ld->topology, false);
		if (!*max_feerate)
			*max_feerate = final_commit_feerate;
		/* No other limit on fees */
		feelimit = channel->funding_sats;
	} else
		max_feerate = NULL;

	min_feerate = feerate_min(ld, NULL);

	/* If they specified feerates in `close`, they apply now! */
	if (channel->closing_feerate_range) {
		min_feerate = channel->closing_feerate_range[0];
		max_feerate = &channel->closing_feerate_range[1];
	}

	/* BOLT #3:
	 *
	 * Each node offering a signature:
	 *  - MUST round each output down to whole satoshis.
	 */
	/* What is not ours is theirs */
	if (!amount_sat_sub_msat(&their_msat,
				 channel->funding_sats, channel->our_msat)) {
		log_broken(channel->log, "our_msat overflow funding %s minus %s",
			  type_to_string(tmpctx, struct amount_sat,
					 &channel->funding_sats),
			  type_to_string(tmpctx, struct amount_msat,
					 &channel->our_msat));
		channel_fail_permanent(channel,
				       REASON_LOCAL,
				       "our_msat overflow on closing");
		return;
	}

	// Determine the wallet index for our output or NULL if not found.
	u32 *local_wallet_index = NULL;
	struct ext_key *local_wallet_ext_key = NULL;
	u32 index_val;
	struct ext_key ext_key_val;
	bool is_p2sh;
	if (wallet_can_spend(
		    ld->wallet,
		    channel->shutdown_scriptpubkey[LOCAL],
		    &index_val,
		    &is_p2sh)) {
		if (bip32_key_from_parent(
			    ld->bip32_base,
			    index_val,
			    BIP32_FLAG_KEY_PUBLIC,
			    &ext_key_val) != WALLY_OK) {
			channel_internal_error(channel, "Could not derive ext public key");
			return;
		}
		local_wallet_index = &index_val;
		local_wallet_ext_key = &ext_key_val;
	}

	initmsg = towire_closingd_init(tmpctx,
				       chainparams,
				       &channel->cid,
				       &channel->funding,
				       channel->funding_sats,
				       &channel->local_funding_pubkey,
				       &channel->channel_info.remote_fundingkey,
				       channel->opener,
				       amount_msat_to_sat_round_down(channel->our_msat),
				       amount_msat_to_sat_round_down(their_msat),
				       channel->our_config.dust_limit,
				       min_feerate, feerate, max_feerate,
				       feelimit,
				       local_wallet_index,
				       local_wallet_ext_key,
				       channel->shutdown_scriptpubkey[LOCAL],
				       channel->shutdown_scriptpubkey[REMOTE],
				       channel->closing_fee_negotiation_step,
				       channel->closing_fee_negotiation_step_unit,
					/* Don't quickclose if they specified how to negotiate! */
				       (channel->closing_fee_negotiation_step == 50
					&& channel->closing_fee_negotiation_step_unit == CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE)
				       /* Always use quickclose with anchors */
				       || option_anchor_outputs
				       || option_anchors_zero_fee_htlc_tx,
				       channel->shutdown_wrong_funding);

	/* We don't expect a response: it will give us feedback on
	 * signatures sent and received, then closing_complete. */
	subd_send_msg(channel->owner, take(initmsg));

	/* Now tell gossipd that we're closing and that neither direction should
	 * be used. */
	if (channel->scid)
		subd_send_msg(channel->peer->ld->gossip,
			      take(towire_gossipd_local_channel_close(
				  tmpctx, channel->scid)));
}

static struct command_result *param_outpoint(struct command *cmd,
					     const char *name,
					     const char *buffer,
					     const jsmntok_t *tok,
					     struct bitcoin_outpoint **outp)
{
	*outp = tal(cmd, struct bitcoin_outpoint);
	if (json_to_outpoint(buffer, tok, *outp))
		return NULL;
	return command_fail_badparam(cmd, name, buffer, tok,
				     "should be a txid:outnum");
}

static struct command_result *param_feerate_range(struct command *cmd,
						  const char *name,
						  const char *buffer,
						  const jsmntok_t *tok,
						  u32 **feerate_range)
{
	struct command_result *ret;
	u32 *rate;

	*feerate_range = tal_arr(cmd, u32, 2);
	if (tok->type != JSMN_ARRAY || tok->size != 2)
		return command_fail_badparam(cmd, name, buffer, tok,
					     "should be an array of 2 entries");

	ret = param_feerate(cmd, name, buffer, tok+1, &rate);
	if (ret)
		return ret;
	(*feerate_range)[0] = *rate;
	ret = param_feerate(cmd, name, buffer, tok+2, &rate);
	if (ret)
		return ret;
	(*feerate_range)[1] = *rate;
	return NULL;
}

/* Only one of these will be set! */
struct some_channel {
	struct channel *channel;
	struct channel *unsaved_channel;
	struct uncommitted_channel *uc;
};

static struct command_result *param_channel_or_peer(struct command *cmd,
						    const char *name,
						    const char *buffer,
						    const jsmntok_t *tok,
						    struct some_channel **sc)
{
	struct peer *peer = peer_from_json(cmd->ld, buffer, tok);
	bool more_than_one;

	(*sc)->unsaved_channel = NULL;
	(*sc)->uc = NULL;

	if (peer) {
		(*sc)->channel = peer_any_active_channel(peer, &more_than_one);
		if ((*sc)->channel) {
			if (more_than_one)
				goto more_than_one;
			return NULL;
		}
	} else {
		struct command_result *res;
		res = command_find_channel(cmd, buffer, tok, &(*sc)->channel);
		if (res)
			return res;
		assert((*sc)->channel);
		return NULL;
	}

	/* OK, we have a peer, but no active channels. */
	(*sc)->uc = peer->uncommitted_channel;
	if ((*sc)->uc)
		return NULL;

	(*sc)->unsaved_channel = peer_any_unsaved_channel(peer, &more_than_one);
	if ((*sc)->unsaved_channel) {
		if (more_than_one)
			goto more_than_one;
		return NULL;
	}

	return command_fail(cmd, LIGHTNINGD, "Peer has no active channel");

more_than_one:
	return command_fail(cmd, LIGHTNINGD,
			    "Peer has multiple channels: use channel_id or short_channel_id");
}

static struct command_result *json_close(struct command *cmd,
					 const char *buffer,
					 const jsmntok_t *obj UNNEEDED,
					 const jsmntok_t *params)
{
	struct channel *channel;
	unsigned int *timeout;
	const u8 *close_to_script = NULL;
	u32 *final_index;
	u32 index_val;
	bool close_script_set, wrong_funding_changed, *force_lease_close;
	const char *fee_negotiation_step_str;
	struct bitcoin_outpoint *wrong_funding;
	u32 *feerate_range;
	char* end;
	bool anysegwit;
	struct some_channel *sc = talz(tmpctx, struct some_channel);

	if (!param(cmd, buffer, params,
		   p_req("id", param_channel_or_peer, &sc),
		   p_opt_def("unilateraltimeout", param_number, &timeout,
			     48 * 3600),
		   p_opt("destination", param_bitcoin_address, &close_to_script),
		   p_opt("fee_negotiation_step", param_string,
			 &fee_negotiation_step_str),
		   p_opt("wrong_funding", param_outpoint, &wrong_funding),
		   p_opt_def("force_lease_closed", param_bool,
			     &force_lease_close, false),
		   p_opt("feerange", param_feerate_range, &feerate_range),
		   NULL))
		return command_param_failed();

	/* Easy cases: peer can simply be forgotten. */
	if (sc->uc) {
		kill_uncommitted_channel(sc->uc, "close command called");
		goto discard_unopened;
	}

	if (sc->unsaved_channel) {
		channel_unsaved_close_conn(sc->unsaved_channel,
					   "close command called");
		goto discard_unopened;
	}

	channel = sc->channel;
	assert(channel);

	if (!*force_lease_close && sc->channel->opener != LOCAL
	    && get_block_height(cmd->ld->topology) < channel->lease_expiry)
		return command_fail(cmd, LIGHTNINGD,
				    "Peer leased this channel from us, we"
				    " shouldn't close until lease has expired"
				    " (lease expires block %u,"
				    " current block %u)",
				    channel->lease_expiry,
				    get_block_height(cmd->ld->topology));

	/* Set the wallet index to the default value; it is updated
	 * below if the close_to_script is found to be in the
	 * wallet. If the close_to_script is not in the wallet
	 * final_index will be set to NULL instead.*/
	assert(channel->final_key_idx <= UINT32_MAX);
	index_val = (u32) channel->final_key_idx;
	final_index = &index_val;

	/* Don't send a scriptpubkey peer won't accept */
	anysegwit = !chainparams->is_elements && feature_negotiated(cmd->ld->our_features,
				       channel->peer->their_features,
				       OPT_SHUTDOWN_ANYSEGWIT);

	/* If we've set a local shutdown script for this peer, and it's not the
	 * default upfront script, try to close to a different channel.
	 * Error is an operator error */
	if (close_to_script && channel->shutdown_scriptpubkey[LOCAL]
			&& !memeq(close_to_script,
				  tal_count(close_to_script),
				  channel->shutdown_scriptpubkey[LOCAL],
				  tal_count(channel->shutdown_scriptpubkey[LOCAL]))) {
		u8 *default_close_to = NULL;
		if (anysegwit)
			default_close_to = p2tr_for_keyidx(tmpctx, cmd->ld,
							  				   channel->final_key_idx);
		else
            default_close_to = p2wpkh_for_keyidx(tmpctx, cmd->ld,
							  					 channel->final_key_idx);
		if (!memeq(default_close_to, tal_count(default_close_to),
			   channel->shutdown_scriptpubkey[LOCAL],
			   tal_count(channel->shutdown_scriptpubkey[LOCAL]))) {
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Destination address %s does not match "
					    "previous shutdown script %s",
					    tal_hex(tmpctx, channel->shutdown_scriptpubkey[LOCAL]),
					    tal_hex(tmpctx, close_to_script));
		} else {
			channel->shutdown_scriptpubkey[LOCAL] =
				tal_free(channel->shutdown_scriptpubkey[LOCAL]);
			channel->shutdown_scriptpubkey[LOCAL] =
				tal_steal(channel, close_to_script);
			close_script_set = true;
		}
	} else if (close_to_script && !channel->shutdown_scriptpubkey[LOCAL]) {
		channel->shutdown_scriptpubkey[LOCAL]
			= tal_steal(channel, cast_const(u8 *, close_to_script));
		close_script_set = true;
		/* Is the close script in our wallet? */
		bool is_p2sh;
		if (wallet_can_spend(
			    cmd->ld->wallet,
			    channel->shutdown_scriptpubkey[LOCAL],
			    &index_val,
			    &is_p2sh)) {
			/* index_val has been set to the discovered wallet index */
		} else {
			final_index = NULL;
		}
	} else if (!channel->shutdown_scriptpubkey[LOCAL]) {
		channel->shutdown_scriptpubkey[LOCAL]
			= p2wpkh_for_keyidx(channel, cmd->ld, channel->final_key_idx);
		/* We don't save the default to disk */
		close_script_set = false;
	} else
		close_script_set = false;

	if (!valid_shutdown_scriptpubkey(channel->shutdown_scriptpubkey[LOCAL],
					 anysegwit, false)) {
		/* Explicit check for future segwits. */
		if (!anysegwit &&
		    valid_shutdown_scriptpubkey(channel->shutdown_scriptpubkey
						[LOCAL], true, false)) {
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Peer does not allow v1+ shutdown addresses");
		}

		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Invalid close destination");
	}

	if (fee_negotiation_step_str == NULL) {
		channel->closing_fee_negotiation_step = 50;
		channel->closing_fee_negotiation_step_unit =
		    CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE;
	} else {
		channel->closing_fee_negotiation_step =
		    strtoull(fee_negotiation_step_str, &end, 10);

		if (channel->closing_fee_negotiation_step == 0)
			return command_fail(
			    cmd, JSONRPC2_INVALID_PARAMS,
			    "Wrong value given for fee_negotiation_step: "
			    "\"%s\", must be positive",
			    fee_negotiation_step_str);
		else if (*end == '%') {
			if (channel->closing_fee_negotiation_step > 100)
				return command_fail(
				    cmd, JSONRPC2_INVALID_PARAMS,
				    "Wrong value given for "
				    "fee_negotiation_step: \"%s\", the "
				    "percentage should be between 1 and 100",
				    fee_negotiation_step_str);
			channel->closing_fee_negotiation_step_unit =
			    CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE;
		} else if (*end == '\0')
			channel->closing_fee_negotiation_step_unit =
			    CLOSING_FEE_NEGOTIATION_STEP_UNIT_SATOSHI;
		else
			return command_fail(
			    cmd, JSONRPC2_INVALID_PARAMS,
			    "Wrong value given for fee_negotiation_step: "
			    "\"%s\", should be an integer or an integer "
			    "followed by %%",
			    fee_negotiation_step_str);
	}

	if (wrong_funding) {
		if (!feature_negotiated(cmd->ld->our_features,
					channel->peer->their_features,
					OPT_SHUTDOWN_WRONG_FUNDING)) {
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "wrong_funding feature not negotiated"
					    " (we said %s, they said %s: try experimental-shutdown-wrong-funding?)",
					    feature_offered(cmd->ld->our_features
							    ->bits[INIT_FEATURE],
							    OPT_SHUTDOWN_WRONG_FUNDING)
					    ? "yes" : "no",
					    feature_offered(channel->peer->their_features,
							    OPT_SHUTDOWN_WRONG_FUNDING)
					    ? "yes" : "no");
		}

		wrong_funding_changed = true;
		channel->shutdown_wrong_funding
			= tal_steal(channel, wrong_funding);
	} else {
		if (channel->shutdown_wrong_funding) {
			channel->shutdown_wrong_funding
				= tal_free(channel->shutdown_wrong_funding);
			wrong_funding_changed = true;
		} else
			wrong_funding_changed = false;
	}

	/* May already be set by previous close cmd. */
	tal_free(channel->closing_feerate_range);

	/* Works fine if feerate_range is NULL */
	channel->closing_feerate_range = tal_steal(channel, feerate_range);

	/* Normal case.
	 * We allow states shutting down and sigexchange; a previous
	 * close command may have timed out, and this current command
	 * will continue waiting for the effects of the previous
	 * close command. */

	/* If normal or locking in, transition to shutting down
	 * state.
	 * (if already shutting down or sigexchange, just keep
	 * waiting) */
	switch (channel->state) {
		case CHANNELD_NORMAL:
		case CHANNELD_AWAITING_LOCKIN:
		case DUALOPEND_AWAITING_LOCKIN:
			channel_set_state(channel,
					  channel->state, CHANNELD_SHUTTING_DOWN,
					  REASON_USER,
					  "User or plugin invoked close command");
			/* fallthrough */
		case CHANNELD_SHUTTING_DOWN:
			if (channel->owner) {
				u8 *msg;
				if (streq(channel->owner->name, "dualopend")) {
					msg = towire_dualopend_send_shutdown(
						NULL,
						channel->shutdown_scriptpubkey[LOCAL]);
				} else {
					struct ext_key ext_key_val;
					struct ext_key *final_ext_key = NULL;
					if (final_index) {
						if (bip32_key_from_parent(
							    channel->peer->ld->bip32_base,
							    *final_index,
							    BIP32_FLAG_KEY_PUBLIC,
							    &ext_key_val) != WALLY_OK) {
							return command_fail(
								cmd, LIGHTNINGD,
								"Could not derive final_ext_key");
						}
						final_ext_key = &ext_key_val;
					}
					msg = towire_channeld_send_shutdown(
						NULL,
						final_index,
						final_ext_key,
						channel->shutdown_scriptpubkey[LOCAL],
						channel->shutdown_wrong_funding);
				}
				subd_send_msg(channel->owner, take(msg));
			}

			break;
		case CLOSINGD_SIGEXCHANGE:
			break;
		default:
			return command_fail(cmd, LIGHTNINGD, "Channel is in state %s",
					    channel_state_name(channel));
	}

	/* Register this command for later handling. */
	register_close_command(cmd->ld, cmd, channel, *timeout);

	/* If we set `channel->shutdown_scriptpubkey[LOCAL]` or
	 * changed shutdown_wrong_funding, save it. */
	if (close_script_set || wrong_funding_changed)
		wallet_channel_save(cmd->ld->wallet, channel);

	/* Wait until close drops down to chain. */
	return command_still_pending(cmd);

discard_unopened: {
	struct json_stream *result = json_stream_success(cmd);
	json_add_string(result, "type", "unopened");
	return command_success(cmd, result);
	}
}

static const struct json_command close_command = {
	"close",
	"channels",
	json_close,
	"Close the channel with {id} "
	"(either peer ID, channel ID, or short channel ID). "
	"Force a unilateral close after {unilateraltimeout} seconds (default 48h). "
	"If {destination} address is provided, will be used as output address."
};
AUTODATA(json_command, &close_command);
