// SPDX-License-Identifier: 0BSD


#include <algorithm>
#include <cassert>
#include <cstring>

extern "C" {
#include "quote.h"
}


static char * quote(const char * beg, const char * end, char * cur) {
	*cur++ = '\'';
	for(; beg != end; ++beg)
		if(*beg == '\'') {
			*cur++ = '\'';
			*cur++ = '\\';
			*cur++ = '\'';
			*cur++ = '\'';
		} else
			*cur++ = *beg;
	*cur++ = '\'';
	return cur;
}


/* Turn "abc %s def %s", "qwe'rt" into "abc 'qwe'\''rt' def %s"
 *   or "ghi",           "qwe'rt" into "ghi 'qwe'\''rt'"
 */
extern "C" char * quotesub(const char * execline, size_t execlinelen, const char * url, size_t urllen) {
	assert(execline);
	assert(url);

	auto pct_s = static_cast<const char *>(memmem(execline, execlinelen, "%s", 2));

	//                                  %s   SPC  '                                                        '   NUL
	auto space = execlinelen + (pct_s ? -2 : 1) + 1 + urllen + (std::count(url, url + urllen, '\'') * 3) + 1 + 1;

	auto ret = reinterpret_cast<char *>(std::malloc(space)), cur = ret;
	if(pct_s) {
		cur = std::copy(execline, pct_s, cur);
		cur = quote(url, url + urllen, cur);
		cur = std::copy(pct_s + 2, execline + execlinelen, cur);
	} else {
		cur    = std::copy(execline, execline + execlinelen, cur);
		*cur++ = ' ';
		cur    = quote(url, url + urllen, cur);
	}
	*cur++ = '\0';
	return ret;
}

// #include <cstdio>
// int main() {
// 	std::puts(quotesub("abc %s def %s", strlen("abc %s def %s"), "qwe'rt", strlen("qwe'rt")));
// 	std::puts(quotesub("ghi", strlen("ghi"), "qwe'rt", strlen("qwe'rt")));
// }
