/* See LICENSE file for copyright and license details. */
#include <stdbool.h>
#include <stddef.h>

#include "../gen/bidirectional.h"
#include "../grapheme.h"
#include "util.h"

#define MAX_DEPTH 125

enum state_type {
	STATE_PROP,            /* in 0..23, bidi_property */
	STATE_PRESERVED_PROP,  /* in 0..23, preserved bidi_prop for L1-rule */
	STATE_BRACKET_OFF,     /* in 0..255, offset in bidi_bracket */
	STATE_LEVEL,           /* in 0..MAX_DEPTH+1=126, embedding level */
	STATE_PARAGRAPH_LEVEL, /* in 0..1, paragraph embedding level */
	STATE_VISITED,         /* in 0..1, visited within isolating run */
};

static struct {
	uint_least32_t filter_mask;
	size_t mask_shift;
	int_least16_t value_offset;
} state_lut[] = {
	[STATE_PROP] = {
		.filter_mask  = 0x000001F, /* 00000000 00000000 00000000 00011111 */
		.mask_shift   = 0,
		.value_offset = 0,
	},
	[STATE_PRESERVED_PROP] = {
		.filter_mask  = 0x00003E0, /* 00000000 00000000 00000011 11100000 */
		.mask_shift   = 5,
		.value_offset = 0,
	},
	[STATE_BRACKET_OFF] = {
		.filter_mask  = 0x003FC00, /* 00000000 00000011 11111100 00000000 */
		.mask_shift   = 10,
		.value_offset = 0,
	},
	[STATE_LEVEL] = {
		.filter_mask  = 0x1FC0000, /* 00000001 11111100 00000000 00000000 */
		.mask_shift   = 18,
		.value_offset = -1,
	},
	[STATE_PARAGRAPH_LEVEL] = {
		.filter_mask  = 0x2000000, /* 00000010 00000000 00000000 00000000 */
		.mask_shift   = 25,
		.value_offset = 0,
	},
	[STATE_VISITED] = {
		.filter_mask  = 0x4000000, /* 00000100 00000000 00000000 00000000 */
		.mask_shift   = 26,
		.value_offset = 0,
	},
};

static inline int_least16_t
get_state(enum state_type t, uint_least32_t input)
{
	return (int_least16_t)((input & state_lut[t].filter_mask) >>
	                       state_lut[t].mask_shift) +
	       state_lut[t].value_offset;
}

static inline void
set_state(enum state_type t, int_least16_t value, uint_least32_t *output)
{
	*output &= ~state_lut[t].filter_mask;
	*output |= ((uint_least32_t)(value - state_lut[t].value_offset)
	            << state_lut[t].mask_shift) &
	           state_lut[t].filter_mask;
}

struct isolate_runner {
	uint_least32_t *buf;
	size_t buflen;
	size_t start;

	struct {
		size_t off;
	} prev, cur, next;

	enum bidi_property sos, eos;

	uint_least8_t paragraph_level;
	int_least8_t isolating_run_level;
};

static inline enum bidi_property
ir_get_previous_prop(const struct isolate_runner *ir)
{
	return (ir->prev.off == SIZE_MAX) ?
	               ir->sos :
	               (uint_least8_t)get_state(STATE_PROP,
	                                        ir->buf[ir->prev.off]);
}

static inline enum bidi_property
ir_get_current_prop(const struct isolate_runner *ir)
{
	return (uint_least8_t)get_state(STATE_PROP, ir->buf[ir->cur.off]);
}

static inline enum bidi_property
ir_get_next_prop(const struct isolate_runner *ir)
{
	return (ir->next.off == SIZE_MAX) ?
	               ir->eos :
	               (uint_least8_t)get_state(STATE_PROP,
	                                        ir->buf[ir->next.off]);
}

static inline enum bidi_property
ir_get_current_preserved_prop(const struct isolate_runner *ir)
{
	return (uint_least8_t)get_state(STATE_PRESERVED_PROP,
	                                ir->buf[ir->cur.off]);
}

static inline int_least8_t
ir_get_current_level(const struct isolate_runner *ir)
{
	return (int_least8_t)get_state(STATE_LEVEL, ir->buf[ir->cur.off]);
}

static inline const struct bracket *
ir_get_current_bracket_prop(const struct isolate_runner *ir)
{
	return bidi_bracket +
	       (int_least8_t)get_state(STATE_BRACKET_OFF, ir->buf[ir->cur.off]);
}

static void
ir_set_current_prop(const struct isolate_runner *ir, enum bidi_property prop)
{
	set_state(STATE_PROP, (int_least16_t)prop, &(ir->buf[ir->cur.off]));
}

static void
ir_init(uint_least32_t *buf, size_t buflen, size_t off,
        uint_least8_t paragraph_level, bool within, struct isolate_runner *ir)
{
	size_t i;
	int_least8_t sos_level;

	/* initialize invariants */
	ir->buf = buf;
	ir->buflen = buflen;
	ir->paragraph_level = paragraph_level;
	ir->start = off;

	/* advance off until we are at a non-removed character */
	for (; off < buflen; off++) {
		if (get_state(STATE_LEVEL, buf[off]) != -1) {
			break;
		}
	}
	if (off == buflen) {
		/* we encountered no more non-removed character, terminate */
		ir->next.off = SIZE_MAX;
		return;
	}

	/* set the isolating run level to that of the current offset */
	ir->isolating_run_level =
		(int_least8_t)get_state(STATE_LEVEL, buf[off]);

	/* initialize sos and eos to dummy values */
	ir->sos = ir->eos = NUM_BIDI_PROPS;

	/*
	 * we write the information of the "current" state into next,
	 * so that the shift-in at the first advancement moves it in
	 * cur, as desired.
	 */
	ir->next.off = off;

	/*
	 * determine the previous state but store its offset in cur.off,
	 * given it's shifted in on the first advancement
	 */
	ir->cur.off = SIZE_MAX;
	for (i = off, sos_level = -1; i >= 1; i--) {
		if (get_state(STATE_LEVEL, buf[i - 1]) != -1) {
			/*
			 * we found a character that has not been
			 * removed in X9
			 */
			sos_level = (int_least8_t)get_state(STATE_LEVEL,
			                                    buf[i - 1]);

			if (within) {
				/* we just take it */
				ir->cur.off = i;
			}

			break;
		}
	}
	if (sos_level == -1) {
		/*
		 * there were no preceding non-removed characters, set
		 * sos-level to paragraph embedding level
		 */
		sos_level = (int_least8_t)paragraph_level;
	}

	if (!within || ir->cur.off == SIZE_MAX) {
		/*
		 * we are at the beginning of the sequence; initialize
		 * it faithfully according to the algorithm by looking
		 * at the sos-level
		 */
		if (MAX(sos_level, ir->isolating_run_level) % 2 == 0) {
			/* the higher level is even, set sos to L */
			ir->sos = BIDI_PROP_L;
		} else {
			/* the higher level is odd, set sos to R */
			ir->sos = BIDI_PROP_R;
		}
	}
}

static int
ir_advance(struct isolate_runner *ir)
{
	enum bidi_property prop;
	int_least8_t level, isolate_level, last_isolate_level;
	size_t i;

	if (ir->next.off == SIZE_MAX) {
		/* the sequence is over */
		return 1;
	}

	/* shift in */
	ir->prev.off = ir->cur.off;
	ir->cur.off = ir->next.off;

	/* mark as visited */
	set_state(STATE_VISITED, 1, &(ir->buf[ir->cur.off]));

	/* initialize next state by going to the next character in the sequence
	 */
	ir->next.off = SIZE_MAX;

	last_isolate_level = -1;
	for (i = ir->cur.off, isolate_level = 0; i < ir->buflen; i++) {
		level = (int_least8_t)get_state(STATE_LEVEL, ir->buf[i]);
		prop = (uint_least8_t)get_state(STATE_PROP, ir->buf[i]);

		if (level == -1) {
			/* this is one of the ignored characters, skip */
			continue;
		} else if (level == ir->isolating_run_level) {
			last_isolate_level = level;
		}

		/* follow BD8/BD9 and P2 to traverse the current sequence */
		if (prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
		    prop == BIDI_PROP_FSI) {
			/*
			 * we encountered an isolate initiator, increment
			 * counter, but go into processing when we
			 * were not isolated before
			 */
			if (isolate_level < MAX_DEPTH) {
				isolate_level++;
			}
			if (isolate_level != 1) {
				continue;
			}
		} else if (prop == BIDI_PROP_PDI && isolate_level > 0) {
			isolate_level--;

			/*
			 * if the current PDI dropped the isolate-level
			 * to zero, it is itself part of the isolating
			 * run sequence; otherwise we simply continue.
			 */
			if (isolate_level > 0) {
				continue;
			}
		} else if (isolate_level > 0) {
			/* we are in an isolating sequence */
			continue;
		}

		/*
		 * now we either still are in our sequence or we hit
		 * the eos-case as we left the sequence and hit the
		 * first non-isolating-sequence character.
		 */
		if (i == ir->cur.off) {
			/* we were in the first initializing round */
			continue;
		} else if (level == ir->isolating_run_level) {
			/* isolate_level-skips have been handled before, we're
			 * good */
			/* still in the sequence */
			ir->next.off = i;
		} else {
			/* out of sequence or isolated, compare levels via eos
			 */
			ir->next.off = SIZE_MAX;
			if (MAX(last_isolate_level, level) % 2 == 0) {
				ir->eos = BIDI_PROP_L;
			} else {
				ir->eos = BIDI_PROP_R;
			}
		}
		break;
	}
	if (i == ir->buflen) {
		/*
		 * the sequence ended before we could grab an offset.
		 * we need to determine the eos-prop by comparing the
		 * level of the last element in the isolating run sequence
		 * with the paragraph level.
		 */
		ir->next.off = SIZE_MAX;
		if (MAX(last_isolate_level, ir->paragraph_level) % 2 == 0) {
			/* the higher level is even, set eos to L */
			ir->eos = BIDI_PROP_L;
		} else {
			/* the higher level is odd, set eos to R */
			ir->eos = BIDI_PROP_R;
		}
	}

	return 0;
}

static enum bidi_property
ir_get_last_strong_prop(const struct isolate_runner *ir)
{
	struct isolate_runner tmp;
	enum bidi_property last_strong_prop = ir->sos, prop;

	ir_init(ir->buf, ir->buflen, ir->start, ir->paragraph_level, false,
	        &tmp);
	for (; !ir_advance(&tmp) && tmp.cur.off < ir->cur.off;) {
		prop = ir_get_current_prop(&tmp);

		if (prop == BIDI_PROP_R || prop == BIDI_PROP_L ||
		    prop == BIDI_PROP_AL) {
			last_strong_prop = prop;
		}
	}

	return last_strong_prop;
}

static enum bidi_property
ir_get_last_strong_or_number_prop(const struct isolate_runner *ir)
{
	struct isolate_runner tmp;
	enum bidi_property last_strong_or_number_prop = ir->sos, prop;

	ir_init(ir->buf, ir->buflen, ir->start, ir->paragraph_level, false,
	        &tmp);
	for (; !ir_advance(&tmp) && tmp.cur.off < ir->cur.off;) {
		prop = ir_get_current_prop(&tmp);

		if (prop == BIDI_PROP_R || prop == BIDI_PROP_L ||
		    prop == BIDI_PROP_AL || prop == BIDI_PROP_EN ||
		    prop == BIDI_PROP_AN) {
			last_strong_or_number_prop = prop;
		}
	}

	return last_strong_or_number_prop;
}

static void
preprocess_bracket_pair(const struct isolate_runner *start,
                        const struct isolate_runner *end)
{
	enum bidi_property prop, bracket_prop, last_strong_or_number_prop;
	struct isolate_runner ir;
	size_t strong_type_off;

	/*
	 * check if the bracket contains a strong type (L or R|EN|AN)
	 */
	for (ir = *start, strong_type_off = SIZE_MAX,
	    bracket_prop = NUM_BIDI_PROPS;
	     !ir_advance(&ir) && ir.cur.off < end->cur.off;) {
		prop = ir_get_current_prop(&ir);

		if (prop == BIDI_PROP_L) {
			strong_type_off = ir.cur.off;
			if (ir.isolating_run_level % 2 == 0) {
				/*
				 * set the type for both brackets to L (so they
				 * match the strong type they contain)
				 */
				bracket_prop = BIDI_PROP_L;
			}
		} else if (prop == BIDI_PROP_R || prop == BIDI_PROP_EN ||
		           prop == BIDI_PROP_AN) {
			strong_type_off = ir.cur.off;
			if (ir.isolating_run_level % 2 != 0) {
				/*
				 * set the type for both brackets to R (so they
				 * match the strong type they contain)
				 */
				bracket_prop = BIDI_PROP_R;
			}
		}
	}
	if (strong_type_off == SIZE_MAX) {
		/*
		 * there are no strong types within the brackets and we just
		 * leave the brackets as is
		 */
		return;
	}

	if (bracket_prop == NUM_BIDI_PROPS) {
		/*
		 * We encountered a strong type, but it was opposite
		 * to the embedding direction.
		 * Check the previous strong type before the opening
		 * bracket
		 */
		last_strong_or_number_prop =
			ir_get_last_strong_or_number_prop(start);
		if (last_strong_or_number_prop == BIDI_PROP_L &&
		    ir.isolating_run_level % 2 != 0) {
			/*
			 * the previous strong type is also opposite
			 * to the embedding direction, so the context
			 * was established and we set the brackets
			 * accordingly.
			 */
			bracket_prop = BIDI_PROP_L;
		} else if ((last_strong_or_number_prop == BIDI_PROP_R ||
		            last_strong_or_number_prop == BIDI_PROP_EN ||
		            last_strong_or_number_prop == BIDI_PROP_AN) &&
		           ir.isolating_run_level % 2 == 0) {
			/*
			 * the previous strong type is also opposite
			 * to the embedding direction, so the context
			 * was established and we set the brackets
			 * accordingly.
			 */
			bracket_prop = BIDI_PROP_R;
		} else {
			/* set brackets to the embedding direction */
			if (ir.isolating_run_level % 2 == 0) {
				bracket_prop = BIDI_PROP_L;
			} else {
				bracket_prop = BIDI_PROP_R;
			}
		}
	}

	ir_set_current_prop(start, bracket_prop);
	ir_set_current_prop(end, bracket_prop);

	/*
	 * any sequence of NSMs after opening or closing brackets get
	 * the same property as the one we set on the brackets
	 */
	for (ir = *start; !ir_advance(&ir) && ir_get_current_preserved_prop(
						      &ir) == BIDI_PROP_NSM;) {
		ir_set_current_prop(&ir, bracket_prop);
	}
	for (ir = *end; !ir_advance(&ir) &&
	                ir_get_current_preserved_prop(&ir) == BIDI_PROP_NSM;) {
		ir_set_current_prop(&ir, bracket_prop);
	}
}

static void
preprocess_bracket_pairs(uint_least32_t *buf, size_t buflen, size_t off,
                         uint_least8_t paragraph_level)
{
	/*
	 * The N0-rule deals with bracket pairs that shall be determined
	 * with the rule BD16. This is specified as an algorithm with a
	 * stack of 63 bracket openings that are used to resolve into a
	 * separate list of pairs, which is then to be sorted by opening
	 * position. Thus, even though the bracketing-depth is limited
	 * by 63, the algorithm, as is, requires dynamic memory
	 * management.
	 *
	 * A naive approach (used by Fribidi) would be to screw the
	 * stack-approach and simply directly determine the
	 * corresponding closing bracket offset for a given opening
	 * bracket, leading to O(n²) time complexity in the worst case
	 * with a lot of brackets. While many brackets are not common,
	 * it is still possible to find a middle ground where you obtain
	 * strongly linear time complexity in most common cases:
	 *
	 * Instead of a stack, we use a FIFO data structure which is
	 * filled with bracket openings in the order of appearance (thus
	 * yielding an implicit sorting!) at the top. If the
	 * corresponding closing bracket is encountered, it is added to
	 * the respective entry, making it ready to "move out" at the
	 * bottom (i.e. passed to the bracket processing). Due to the
	 * nature of the specified pair detection algorithm, which only
	 * cares about the bracket type and nothing else (bidi class,
	 * level, etc.), we can mix processing and bracket detection.
	 *
	 * Obviously, if you, for instance, have one big bracket pair at
	 * the bottom that has not been closed yet, it will block the
	 * bracket processing and the FIFO might hit its capacity limit.
	 * At this point, the blockage is manually resolved using the
	 * naive quadratic approach.
	 *
	 * To remain within the specified standard behaviour, which
	 * mandates that processing of brackets should stop when the
	 * bracketing-depth is at 63, we simply check in an "overflow"
	 * scenario if all 63 elements in the LIFO are unfinished, which
	 * corresponds with such a bracketing depth.
	 */
	enum bidi_property prop;

	struct {
		bool complete;
		size_t bracket_class;
		struct isolate_runner start;
		struct isolate_runner end;
	} fifo[63];
	const struct bracket *bracket_prop, *tmp_bracket_prop;
	struct isolate_runner ir, tmp_ir;
	size_t fifo_len = 0, i, blevel, j, k;

	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		prop = ir_get_current_prop(&ir);
		bracket_prop = ir_get_current_bracket_prop(&ir);
		if (prop == BIDI_PROP_ON &&
		    bracket_prop->type == BIDI_BRACKET_OPEN) {
			if (fifo_len == LEN(fifo)) {
				/*
				 * The FIFO is full, check first if it's
				 * completely blocked (i.e. no finished
				 * bracket pairs, triggering the standard
				 * that mandates to abort in such a case
				 */
				for (i = 0; i < fifo_len; i++) {
					if (fifo[i].complete) {
						break;
					}
				}
				if (i == fifo_len) {
					/* abort processing */
					return;
				}

				/*
				 * by construction, the bottom entry
				 * in the FIFO is guaranteed to be
				 * unfinished (given we "consume" all
				 * finished bottom entries after each
				 * iteration).
				 *
				 * iterate, starting after the opening
				 * bracket, and find the corresponding
				 * closing bracket.
				 *
				 * if we find none, just drop the FIFO
				 * entry silently
				 */
				for (tmp_ir = fifo[0].start, blevel = 0;
				     !ir_advance(&tmp_ir);) {
					tmp_bracket_prop =
						ir_get_current_bracket_prop(
							&tmp_ir);

					if (tmp_bracket_prop->type ==
					            BIDI_BRACKET_OPEN &&
					    tmp_bracket_prop->class ==
					            bracket_prop->class) {
						/* we encountered another
						 * opening bracket of the
						 * same class */
						blevel++;

					} else if (tmp_bracket_prop->type ==
					                   BIDI_BRACKET_CLOSE &&
					           tmp_bracket_prop->class ==
					                   bracket_prop
					                           ->class) {
						/* we encountered a closing
						 * bracket of the same class
						 */
						if (blevel == 0) {
							/* this is the
							 * corresponding
							 * closing bracket
							 */
							fifo[0].complete = true;
							fifo[0].end = ir;
						} else {
							blevel--;
						}
					}
				}
				if (fifo[0].complete) {
					/* we found the matching bracket */
					preprocess_bracket_pair(
						&(fifo[i].start),
						&(fifo[i].end));
				}

				/* shift FIFO one to the left */
				for (i = 1; i < fifo_len; i++) {
					fifo[i - 1] = fifo[i];
				}
				fifo_len--;
			}

			/* add element to the FIFO */
			fifo_len++;
			fifo[fifo_len - 1].complete = false;
			fifo[fifo_len - 1].bracket_class = bracket_prop->class;
			fifo[fifo_len - 1].start = ir;
		} else if (prop == BIDI_PROP_ON &&
		           bracket_prop->type == BIDI_BRACKET_CLOSE) {
			/*
			 * go backwards in the FIFO, skip finished entries
			 * and simply ignore (do nothing) the closing
			 * bracket if we do not match anything
			 */
			for (i = fifo_len; i > 0; i--) {
				if (bracket_prop->class ==
				            fifo[i - 1].bracket_class &&
				    !fifo[i - 1].complete) {
					/* we have found a pair */
					fifo[i - 1].complete = true;
					fifo[i - 1].end = ir;

					/* remove all uncompleted FIFO elements
					 * above i - 1 */
					for (j = i; j < fifo_len;) {
						if (fifo[j].complete) {
							j++;
							continue;
						}

						/* shift FIFO one to the left */
						for (k = j + 1; k < fifo_len;
						     k++) {
							fifo[k - 1] = fifo[k];
						}
						fifo_len--;
					}
					break;
				}
			}
		}

		/* process all ready bracket pairs from the FIFO bottom */
		while (fifo_len > 0 && fifo[0].complete) {
			preprocess_bracket_pair(&(fifo[0].start),
			                        &(fifo[0].end));

			/* shift FIFO one to the left */
			for (j = 0; j + 1 < fifo_len; j++) {
				fifo[j] = fifo[j + 1];
			}
			fifo_len--;
		}
	}

	/*
	 * afterwards, we still might have unfinished bracket pairs
	 * that will remain as such, but the subsequent finished pairs
	 * also need to be taken into account, so we go through the
	 * FIFO once more and process all finished pairs
	 */
	for (i = 0; i < fifo_len; i++) {
		if (fifo[i].complete) {
			preprocess_bracket_pair(&(fifo[i].start),
			                        &(fifo[i].end));
		}
	}
}

static size_t
preprocess_isolating_run_sequence(uint_least32_t *buf, size_t buflen,
                                  size_t off, uint_least8_t paragraph_level)
{
	enum bidi_property sequence_prop, prop;
	struct isolate_runner ir, tmp;
	size_t runsince, sequence_end;

	/* W1 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_current_prop(&ir) == BIDI_PROP_NSM) {
			prop = ir_get_previous_prop(&ir);

			if (prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
			    prop == BIDI_PROP_FSI || prop == BIDI_PROP_PDI) {
				ir_set_current_prop(&ir, BIDI_PROP_ON);
			} else {
				ir_set_current_prop(&ir, prop);
			}
		}
	}

	/* W2 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_current_prop(&ir) == BIDI_PROP_EN &&
		    ir_get_last_strong_prop(&ir) == BIDI_PROP_AL) {
			ir_set_current_prop(&ir, BIDI_PROP_AN);
		}
	}

	/* W3 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_current_prop(&ir) == BIDI_PROP_AL) {
			ir_set_current_prop(&ir, BIDI_PROP_R);
		}
	}

	/* W4 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_previous_prop(&ir) == BIDI_PROP_EN &&
		    (ir_get_current_prop(&ir) == BIDI_PROP_ES ||
		     ir_get_current_prop(&ir) == BIDI_PROP_CS) &&
		    ir_get_next_prop(&ir) == BIDI_PROP_EN) {
			ir_set_current_prop(&ir, BIDI_PROP_EN);
		}

		if (ir_get_previous_prop(&ir) == BIDI_PROP_AN &&
		    ir_get_current_prop(&ir) == BIDI_PROP_CS &&
		    ir_get_next_prop(&ir) == BIDI_PROP_AN) {
			ir_set_current_prop(&ir, BIDI_PROP_AN);
		}
	}

	/* W5 */
	runsince = SIZE_MAX;
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_current_prop(&ir) == BIDI_PROP_ET) {
			if (runsince == SIZE_MAX) {
				/* a new run has begun */
				runsince = ir.cur.off;
			}
		} else if (ir_get_current_prop(&ir) == BIDI_PROP_EN) {
			/* set the preceding sequence */
			if (runsince != SIZE_MAX) {
				ir_init(buf, buflen, runsince, paragraph_level,
				        (runsince > off), &tmp);
				while (!ir_advance(&tmp) &&
				       tmp.cur.off < ir.cur.off) {
					ir_set_current_prop(&tmp, BIDI_PROP_EN);
				}
				runsince = SIZE_MAX;
			} else {
				ir_init(buf, buflen, ir.cur.off,
				        paragraph_level, (ir.cur.off > off),
				        &tmp);
				ir_advance(&tmp);
			}
			/* follow the succeeding sequence */
			while (!ir_advance(&tmp)) {
				if (ir_get_current_prop(&tmp) != BIDI_PROP_ET) {
					break;
				}
				ir_set_current_prop(&tmp, BIDI_PROP_EN);
			}
		} else {
			/* sequence ended */
			runsince = SIZE_MAX;
		}
	}

	/* W6 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		prop = ir_get_current_prop(&ir);

		if (prop == BIDI_PROP_ES || prop == BIDI_PROP_ET ||
		    prop == BIDI_PROP_CS) {
			ir_set_current_prop(&ir, BIDI_PROP_ON);
		}
	}

	/* W7 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (ir_get_current_prop(&ir) == BIDI_PROP_EN &&
		    ir_get_last_strong_prop(&ir) == BIDI_PROP_L) {
			ir_set_current_prop(&ir, BIDI_PROP_L);
		}
	}

	/* N0 */
	preprocess_bracket_pairs(buf, buflen, off, paragraph_level);

	/* N1 */
	sequence_end = SIZE_MAX;
	sequence_prop = NUM_BIDI_PROPS;
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		if (sequence_end == SIZE_MAX) {
			prop = ir_get_current_prop(&ir);

			if (prop == BIDI_PROP_B || prop == BIDI_PROP_S ||
			    prop == BIDI_PROP_WS || prop == BIDI_PROP_ON ||
			    prop == BIDI_PROP_FSI || prop == BIDI_PROP_LRI ||
			    prop == BIDI_PROP_RLI || prop == BIDI_PROP_PDI) {
				/* the current character is an NI (neutral
				 * or isolate) */

				/* scan ahead to the end of the NI-sequence
				 */
				ir_init(buf, buflen, ir.cur.off,
				        paragraph_level, (ir.cur.off > off),
				        &tmp);
				while (!ir_advance(&tmp)) {
					prop = ir_get_next_prop(&tmp);

					if (prop != BIDI_PROP_B &&
					    prop != BIDI_PROP_S &&
					    prop != BIDI_PROP_WS &&
					    prop != BIDI_PROP_ON &&
					    prop != BIDI_PROP_FSI &&
					    prop != BIDI_PROP_LRI &&
					    prop != BIDI_PROP_RLI &&
					    prop != BIDI_PROP_PDI) {
						break;
					}
				}

				/*
				 * check what follows and see if the text
				 * has the same direction on both sides
				 */
				if (ir_get_previous_prop(&ir) == BIDI_PROP_L &&
				    ir_get_next_prop(&tmp) == BIDI_PROP_L) {
					sequence_end = tmp.cur.off;
					sequence_prop = BIDI_PROP_L;
				} else if ((ir_get_previous_prop(&ir) ==
				                    BIDI_PROP_R ||
				            ir_get_previous_prop(&ir) ==
				                    BIDI_PROP_EN ||
				            ir_get_previous_prop(&ir) ==
				                    BIDI_PROP_AN) &&
				           (ir_get_next_prop(&tmp) ==
				                    BIDI_PROP_R ||
				            ir_get_next_prop(&tmp) ==
				                    BIDI_PROP_EN ||
				            ir_get_next_prop(&tmp) ==
				                    BIDI_PROP_AN)) {
					sequence_end = tmp.cur.off;
					sequence_prop = BIDI_PROP_R;
				}
			}
		}

		if (sequence_end != SIZE_MAX) {
			if (ir.cur.off <= sequence_end) {
				ir_set_current_prop(&ir, sequence_prop);
			} else {
				/* end of sequence, reset */
				sequence_end = SIZE_MAX;
				sequence_prop = NUM_BIDI_PROPS;
			}
		}
	}

	/* N2 */
	ir_init(buf, buflen, off, paragraph_level, false, &ir);
	while (!ir_advance(&ir)) {
		prop = ir_get_current_prop(&ir);

		if (prop == BIDI_PROP_B || prop == BIDI_PROP_S ||
		    prop == BIDI_PROP_WS || prop == BIDI_PROP_ON ||
		    prop == BIDI_PROP_FSI || prop == BIDI_PROP_LRI ||
		    prop == BIDI_PROP_RLI || prop == BIDI_PROP_PDI) {
			/* N2 */
			if (ir_get_current_level(&ir) % 2 == 0) {
				/* even embedding level */
				ir_set_current_prop(&ir, BIDI_PROP_L);
			} else {
				/* odd embedding level */
				ir_set_current_prop(&ir, BIDI_PROP_R);
			}
		}
	}

	return 0;
}

static uint_least8_t
get_isolated_paragraph_level(const uint_least32_t *state, size_t statelen)
{
	enum bidi_property prop;
	int_least8_t isolate_level;
	size_t stateoff;

	/* determine paragraph level (rules P1-P3) and terminate on PDI */
	for (stateoff = 0, isolate_level = 0; stateoff < statelen; stateoff++) {
		prop = (uint_least8_t)get_state(STATE_PROP, state[stateoff]);

		if (prop == BIDI_PROP_PDI && isolate_level == 0) {
			/*
			 * we are in a FSI-subsection of a paragraph and
			 * matched with the terminating PDI
			 */
			break;
		}

		/* BD8/BD9 */
		if ((prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
		     prop == BIDI_PROP_FSI) &&
		    isolate_level < MAX_DEPTH) {
			/* we hit an isolate initiator, increment counter */
			isolate_level++;
		} else if (prop == BIDI_PROP_PDI && isolate_level > 0) {
			isolate_level--;
		}

		/* P2 */
		if (isolate_level > 0) {
			continue;
		}

		/* P3 */
		if (prop == BIDI_PROP_L) {
			return 0;
		} else if (prop == BIDI_PROP_AL || prop == BIDI_PROP_R) {
			return 1;
		}
	}

	return 0;
}

static inline uint_least8_t
get_bidi_property(uint_least32_t cp)
{
	if (likely(cp <= 0x10FFFF)) {
		return (bidi_minor[bidi_major[cp >> 8] + (cp & 0xff)]) &
		       0x1F /* 00011111 */;
	} else {
		return BIDI_PROP_L;
	}
}

static uint_least8_t
get_paragraph_level(enum grapheme_bidirectional_direction override,
                    const HERODOTUS_READER *r)
{
	HERODOTUS_READER tmp;
	enum bidi_property prop;
	int_least8_t isolate_level;
	uint_least32_t cp;

	/* check overrides first according to rule HL1 */
	if (override == GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR) {
		return 0;
	} else if (override == GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL) {
		return 1;
	}

	/* copy reader into temporary reader */
	herodotus_reader_copy(r, &tmp);

	/* determine paragraph level (rules P1-P3) */
	for (isolate_level = 0; herodotus_read_codepoint(&tmp, true, &cp) ==
	                        HERODOTUS_STATUS_SUCCESS;) {
		prop = get_bidi_property(cp);

		/* BD8/BD9 */
		if ((prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
		     prop == BIDI_PROP_FSI) &&
		    isolate_level < MAX_DEPTH) {
			/* we hit an isolate initiator, increment counter */
			isolate_level++;
		} else if (prop == BIDI_PROP_PDI && isolate_level > 0) {
			isolate_level--;
		}

		/* P2 */
		if (isolate_level > 0) {
			continue;
		}

		/* P3 */
		if (prop == BIDI_PROP_L) {
			return 0;
		} else if (prop == BIDI_PROP_AL || prop == BIDI_PROP_R) {
			return 1;
		}
	}

	return 0;
}

static void
preprocess_paragraph(uint_least8_t paragraph_level, uint_least32_t *buf,
                     size_t buflen)
{
	enum bidi_property prop;
	int_least8_t level;

	struct {
		int_least8_t level;
		enum grapheme_bidirectional_direction override;
		bool directional_isolate;
	} directional_status[MAX_DEPTH + 2], *dirstat = directional_status;

	size_t overflow_isolate_count, overflow_embedding_count,
		valid_isolate_count, bufoff, i, runsince;

	/* X1 */
	dirstat->level = (int_least8_t)paragraph_level;
	dirstat->override = GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL;
	dirstat->directional_isolate = false;
	overflow_isolate_count = overflow_embedding_count =
		valid_isolate_count = 0;

	for (bufoff = 0; bufoff < buflen; bufoff++) {
		prop = (uint_least8_t)get_state(STATE_PROP, buf[bufoff]);

		/* set paragraph level we need for line-level-processing */
		set_state(STATE_PARAGRAPH_LEVEL, paragraph_level,
		          &(buf[bufoff]));
again:
		if (prop == BIDI_PROP_RLE) {
			/* X2 */
			if (dirstat->level + (dirstat->level % 2 != 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid RLE */
				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 != 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL;
				dirstat->directional_isolate = false;
			} else {
				/* overflow RLE */
				overflow_embedding_count +=
					(overflow_isolate_count == 0);
			}
		} else if (prop == BIDI_PROP_LRE) {
			/* X3 */
			if (dirstat->level + (dirstat->level % 2 == 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid LRE */
				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 == 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL;
				dirstat->directional_isolate = false;
			} else {
				/* overflow LRE */
				overflow_embedding_count +=
					(overflow_isolate_count == 0);
			}
		} else if (prop == BIDI_PROP_RLO) {
			/* X4 */
			if (dirstat->level + (dirstat->level % 2 != 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid RLO */
				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 != 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL;
				dirstat->directional_isolate = false;
			} else {
				/* overflow RLO */
				overflow_embedding_count +=
					(overflow_isolate_count == 0);
			}
		} else if (prop == BIDI_PROP_LRO) {
			/* X5 */
			if (dirstat->level + (dirstat->level % 2 == 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid LRE */
				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 == 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR;
				dirstat->directional_isolate = false;
			} else {
				/* overflow LRO */
				overflow_embedding_count +=
					(overflow_isolate_count == 0);
			}
		} else if (prop == BIDI_PROP_RLI) {
			/* X5a */
			set_state(STATE_LEVEL, dirstat->level, &(buf[bufoff]));
			if (dirstat->override ==
			    GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR) {
				set_state(STATE_PROP, BIDI_PROP_L,
				          &(buf[bufoff]));
			} else if (dirstat->override ==
			           GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL) {
				set_state(STATE_PROP, BIDI_PROP_R,
				          &(buf[bufoff]));
			}

			if (dirstat->level + (dirstat->level % 2 != 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid RLI */
				valid_isolate_count++;

				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 != 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL;
				dirstat->directional_isolate = true;
			} else {
				/* overflow RLI */
				overflow_isolate_count++;
			}
		} else if (prop == BIDI_PROP_LRI) {
			/* X5b */
			set_state(STATE_LEVEL, dirstat->level, &(buf[bufoff]));
			if (dirstat->override ==
			    GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR) {
				set_state(STATE_PROP, BIDI_PROP_L,
				          &(buf[bufoff]));
			} else if (dirstat->override ==
			           GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL) {
				set_state(STATE_PROP, BIDI_PROP_R,
				          &(buf[bufoff]));
			}

			if (dirstat->level + (dirstat->level % 2 == 0) + 1 <=
			            MAX_DEPTH &&
			    overflow_isolate_count == 0 &&
			    overflow_embedding_count == 0) {
				/* valid LRI */
				valid_isolate_count++;

				dirstat++;
				dirstat->level =
					(dirstat - 1)->level +
					((dirstat - 1)->level % 2 == 0) + 1;
				dirstat->override =
					GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL;
				dirstat->directional_isolate = true;
			} else {
				/* overflow LRI */
				overflow_isolate_count++;
			}
		} else if (prop == BIDI_PROP_FSI) {
			/* X5c */
			if (get_isolated_paragraph_level(
				    buf + (bufoff + 1),
				    buflen - (bufoff + 1)) == 1) {
				prop = BIDI_PROP_RLI;
				goto again;
			} else { /* ... == 0 */
				prop = BIDI_PROP_LRI;
				goto again;
			}
		} else if (prop != BIDI_PROP_B && prop != BIDI_PROP_BN &&
		           prop != BIDI_PROP_PDF && prop != BIDI_PROP_PDI) {
			/* X6 */
			set_state(STATE_LEVEL, dirstat->level, &(buf[bufoff]));
			if (dirstat->override ==
			    GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR) {
				set_state(STATE_PROP, BIDI_PROP_L,
				          &(buf[bufoff]));
			} else if (dirstat->override ==
			           GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL) {
				set_state(STATE_PROP, BIDI_PROP_R,
				          &(buf[bufoff]));
			}
		} else if (prop == BIDI_PROP_PDI) {
			/* X6a */
			if (overflow_isolate_count > 0) {
				/* PDI matches an overflow isolate initiator
				 */
				overflow_isolate_count--;
			} else if (valid_isolate_count > 0) {
				/* PDI matches a normal isolate initiator */
				overflow_embedding_count = 0;
				while (dirstat->directional_isolate == false &&
				       dirstat > directional_status) {
					/*
					 * we are safe here as given the
					 * valid isolate count is positive
					 * there must be a stack-entry
					 * with positive directional
					 * isolate status, but we take
					 * no chances and include an
					 * explicit check
					 *
					 * POSSIBLE OPTIMIZATION: Whenever
					 * we push on the stack, check if it
					 * has the directional isolate
					 * status true and store a pointer
					 * to it so we can jump to it very
					 * quickly.
					 */
					dirstat--;
				}

				/*
				 * as above, the following check is not
				 * necessary, given we are guaranteed to
				 * have at least one stack entry left,
				 * but it's better to be safe
				 */
				if (dirstat > directional_status) {
					dirstat--;
				}
				valid_isolate_count--;
			}

			set_state(STATE_LEVEL, dirstat->level, &(buf[bufoff]));
			if (dirstat->override ==
			    GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR) {
				set_state(STATE_PROP, BIDI_PROP_L,
				          &(buf[bufoff]));
			} else if (dirstat->override ==
			           GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL) {
				set_state(STATE_PROP, BIDI_PROP_R,
				          &(buf[bufoff]));
			}
		} else if (prop == BIDI_PROP_PDF) {
			/* X7 */
			if (overflow_isolate_count > 0) {
				/* do nothing */
			} else if (overflow_embedding_count > 0) {
				overflow_embedding_count--;
			} else if (dirstat->directional_isolate == false &&
			           dirstat > directional_status) {
				dirstat--;
			}
		} else if (prop == BIDI_PROP_B) {
			/* X8 */
			set_state(STATE_LEVEL, paragraph_level, &(buf[bufoff]));
		}

		/* X9 */
		if (prop == BIDI_PROP_RLE || prop == BIDI_PROP_LRE ||
		    prop == BIDI_PROP_RLO || prop == BIDI_PROP_LRO ||
		    prop == BIDI_PROP_PDF || prop == BIDI_PROP_BN) {
			set_state(STATE_LEVEL, -1, &(buf[bufoff]));
		}
	}

	/* X10 (W1-W7, N0-N2) */
	for (bufoff = 0; bufoff < buflen; bufoff++) {
		if (get_state(STATE_VISITED, buf[bufoff]) == 0 &&
		    get_state(STATE_LEVEL, buf[bufoff]) != -1) {
			bufoff += preprocess_isolating_run_sequence(
				buf, buflen, bufoff, paragraph_level);
		}
	}

	/*
	 * I1-I2 (given our sequential approach to processing the
	 * isolating run sequences, we apply this rule separately)
	 */
	for (bufoff = 0; bufoff < buflen; bufoff++) {
		level = (int_least8_t)get_state(STATE_LEVEL, buf[bufoff]);
		prop = (uint_least8_t)get_state(STATE_PROP, buf[bufoff]);

		if (level % 2 == 0) {
			/* even level */
			if (prop == BIDI_PROP_R) {
				set_state(STATE_LEVEL, level + 1,
				          &(buf[bufoff]));
			} else if (prop == BIDI_PROP_AN ||
			           prop == BIDI_PROP_EN) {
				set_state(STATE_LEVEL, level + 2,
				          &(buf[bufoff]));
			}
		} else {
			/* odd level */
			if (prop == BIDI_PROP_L || prop == BIDI_PROP_EN ||
			    prop == BIDI_PROP_AN) {
				set_state(STATE_LEVEL, level + 1,
				          &(buf[bufoff]));
			}
		}
	}

	/* L1 (rules 1-3) */
	runsince = SIZE_MAX;
	for (bufoff = 0; bufoff < buflen; bufoff++) {
		level = (int_least8_t)get_state(STATE_LEVEL, buf[bufoff]);
		prop = (uint_least8_t)get_state(STATE_PRESERVED_PROP,
		                                buf[bufoff]);

		if (level == -1) {
			/* ignored character */
			continue;
		}

		/* rules 1 and 2 */
		if (prop == BIDI_PROP_S || prop == BIDI_PROP_B) {
			set_state(STATE_LEVEL, paragraph_level, &(buf[bufoff]));
		}

		/* rule 3 */
		if (prop == BIDI_PROP_WS || prop == BIDI_PROP_FSI ||
		    prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
		    prop == BIDI_PROP_PDI) {
			if (runsince == SIZE_MAX) {
				/* a new run has begun */
				runsince = bufoff;
			}
		} else if ((prop == BIDI_PROP_S || prop == BIDI_PROP_B) &&
		           runsince != SIZE_MAX) {
			/*
			 * we hit a segment or paragraph separator in a
			 * sequence, reset sequence-levels
			 */
			for (i = runsince; i < bufoff; i++) {
				if (get_state(STATE_LEVEL, buf[i]) != -1) {
					set_state(STATE_LEVEL, paragraph_level,
					          &(buf[i]));
				}
			}
			runsince = SIZE_MAX;
		} else {
			/* sequence ended */
			runsince = SIZE_MAX;
		}
	}
	if (runsince != SIZE_MAX) {
		/*
		 * this is the end of the paragraph and we
		 * are in a run
		 */
		for (i = runsince; i < buflen; i++) {
			if (get_state(STATE_LEVEL, buf[i]) != -1) {
				set_state(STATE_LEVEL, paragraph_level,
				          &(buf[i]));
			}
		}
		runsince = SIZE_MAX;
	}
}

static inline uint_least8_t
get_bidi_bracket_off(uint_least32_t cp)
{
	if (likely(cp <= 0x10FFFF)) {
		return (uint_least8_t)((bidi_minor[bidi_major[cp >> 8] +
		                                   (cp & 0xff)]) >>
		                       5);
	} else {
		return 0;
	}
}

static size_t
preprocess(HERODOTUS_READER *r, enum grapheme_bidirectional_direction override,
           uint_least32_t *buf, size_t buflen,
           enum grapheme_bidirectional_direction *resolved)
{
	HERODOTUS_READER tmp;
	size_t bufoff, bufsize, paragraph_len;
	uint_least32_t cp;
	uint_least8_t paragraph_level;

	/* determine length and level of the paragraph */
	herodotus_reader_copy(r, &tmp);
	for (; herodotus_read_codepoint(&tmp, true, &cp) ==
	       HERODOTUS_STATUS_SUCCESS;) {
		/* break on paragraph separator */
		if (get_bidi_property(cp) == BIDI_PROP_B) {
			break;
		}
	}
	paragraph_len = herodotus_reader_number_read(&tmp);
	paragraph_level = get_paragraph_level(override, r);

	if (resolved != NULL) {
		/* store resolved paragraph level in output variable */
		/* TODO use enum-type */
		*resolved = (paragraph_level == 0) ?
		                    GRAPHEME_BIDIRECTIONAL_DIRECTION_LTR :
		                    GRAPHEME_BIDIRECTIONAL_DIRECTION_RTL;
	}

	if (buf == NULL) {
		/* see below for return value reasoning */
		return paragraph_len;
	}

	/*
	 * the first step is to determine the bidirectional properties
	 * and store them in the buffer
	 */
	for (bufoff = 0;
	     bufoff < paragraph_len &&
	     herodotus_read_codepoint(r, true, &cp) == HERODOTUS_STATUS_SUCCESS;
	     bufoff++) {
		if (bufoff < buflen) {
			/*
			 * actually only do something when we have
			 * space in the level-buffer. We continue
			 * the iteration to be able to give a good
			 * return value
			 */
			set_state(STATE_PROP,
			          (uint_least8_t)get_bidi_property(cp),
			          &(buf[bufoff]));
			set_state(STATE_BRACKET_OFF, get_bidi_bracket_off(cp),
			          &(buf[bufoff]));
			set_state(STATE_LEVEL, 0, &(buf[bufoff]));
			set_state(STATE_PARAGRAPH_LEVEL, 0, &(buf[bufoff]));
			set_state(STATE_VISITED, 0, &(buf[bufoff]));
			set_state(STATE_PRESERVED_PROP,
			          (uint_least8_t)get_bidi_property(cp),
			          &(buf[bufoff]));
		}
	}
	bufsize = herodotus_reader_number_read(r);

	for (bufoff = 0; bufoff < bufsize; bufoff++) {
		if (get_state(STATE_PROP, buf[bufoff]) != BIDI_PROP_B &&
		    bufoff != bufsize - 1) {
			continue;
		}

		/*
		 * we either encountered a paragraph terminator or this
		 * is the last character in the string.
		 * Call the paragraph handler on the paragraph, including
		 * the terminating character or last character of the
		 * string respectively
		 */
		preprocess_paragraph(paragraph_level, buf, bufoff + 1);
		break;
	}

	/*
	 * we return the number of total bytes read, as the function
	 * should indicate if the given level-buffer is too small
	 */
	return herodotus_reader_number_read(r);
}

size_t
grapheme_bidirectional_preprocess_paragraph(
	const uint_least32_t *src, size_t srclen,
	enum grapheme_bidirectional_direction override, uint_least32_t *dest,
	size_t destlen, enum grapheme_bidirectional_direction *resolved)
{
	HERODOTUS_READER r;

	herodotus_reader_init(&r, HERODOTUS_TYPE_CODEPOINT, src, srclen);

	return preprocess(&r, override, dest, destlen, resolved);
}

static inline size_t
get_line_embedding_levels(const uint_least32_t *linedata, size_t linelen,
                          int_least8_t (*get_level)(const void *, size_t),
                          void (*set_level)(void *, size_t, int_least8_t),
                          void *lev, size_t levsize, bool skipignored)
{
	enum bidi_property prop;
	size_t i, levlen, runsince;
	int_least8_t level, runlevel;

	/* rule L1.4 */
	runsince = SIZE_MAX;
	runlevel = -1;
	for (i = 0, levlen = 0; i < linelen; i++) {
		level = (int_least8_t)get_state(STATE_LEVEL, linedata[i]);
		prop = (uint_least8_t)get_state(STATE_PRESERVED_PROP,
		                                linedata[i]);

		/* write level into level array if we still have space */
		if (level != -1 || skipignored == false) {
			if (levlen <= levsize) {
				set_level(lev, levlen, level);
			}
			levlen++;
		}

		if (level == -1) {
			/* ignored character */
			continue;
		}

		if (prop == BIDI_PROP_WS || prop == BIDI_PROP_FSI ||
		    prop == BIDI_PROP_LRI || prop == BIDI_PROP_RLI ||
		    prop == BIDI_PROP_PDI) {
			if (runsince == SIZE_MAX) {
				/* a new run has begun */
				runsince = levlen - 1; /* levlen > 0 */
				runlevel = (int_least8_t)get_state(
					STATE_PARAGRAPH_LEVEL, linedata[i]);
			}
		} else {
			/* sequence ended */
			runsince = SIZE_MAX;
			runlevel = -1;
		}
	}
	if (runsince != SIZE_MAX) {
		/*
		 * we hit the end of the line but were in a run;
		 * reset the line levels to the paragraph level
		 */
		for (i = runsince; i < MIN(linelen, levlen); i++) {
			if (get_level(lev, i) != -1) {
				set_level(lev, i, runlevel);
			}
		}
	}

	return levlen;
}

static inline int_least8_t
get_level_int8(const void *lev, size_t off)
{
	return ((const int_least8_t *)lev)[off];
}

static inline void
set_level_int8(void *lev, size_t off, int_least8_t value)
{
	((int_least8_t *)lev)[off] = value;
}

size_t
grapheme_bidirectional_get_line_embedding_levels(const uint_least32_t *linedata,
                                                 size_t linelen,
                                                 int_least8_t *lev,
                                                 size_t levlen)
{
	return get_line_embedding_levels(linedata, linelen, get_level_int8,
	                                 set_level_int8, lev, levlen, false);
}

static inline int_least8_t
get_level_uint32(const void *lev, size_t off)
{
	return (int_least8_t)((((const uint_least32_t *)lev)[off] &
	                       UINT32_C(0x1FE00000)) >>
	                      21) -
	       1;
}

static inline void
set_level_uint32(void *lev, size_t off, int_least8_t value)
{
	((uint_least32_t *)lev)[off] ^=
		((uint_least32_t *)lev)[off] & UINT32_C(0x1FE00000);
	((uint_least32_t *)lev)[off] |= ((uint_least32_t)(value + 1)) << 21;
}

static inline int_least16_t
get_mirror_offset(uint_least32_t cp)
{
	if (cp <= UINT32_C(0x10FFFF)) {
		return mirror_minor[mirror_major[cp >> 8] + (cp & 0xFF)];
	} else {
		return 0;
	}
}

size_t
grapheme_bidirectional_reorder_line(const uint_least32_t *line,
                                    const uint_least32_t *linedata,
                                    size_t linelen, uint_least32_t *output,
                                    size_t outputsize)
{
	size_t i, outputlen, first, last, j, k, l /*, laststart*/;
	int_least8_t level, min_odd_level = MAX_DEPTH + 2, max_level = 0;
	uint_least32_t tmp;

	/* write output characters (and apply possible mirroring) */
	for (i = 0, outputlen = 0; i < linelen; i++) {
		if (get_state(STATE_LEVEL, linedata[i]) != -1) {
			if (outputlen < outputsize) {
				output[outputlen] =
					(uint_least32_t)((int_least32_t)
				                                 line[i] +
				                         get_mirror_offset(
								 line[i]));
			}
			outputlen++;
		}
	}
	if (outputlen >= outputsize) {
		/* clear output buffer */
		for (i = 0; i < outputsize; i++) {
			output[i] = GRAPHEME_INVALID_CODEPOINT;
		}

		/* return required size */
		return outputlen;
	}

	/*
	 * write line embedding levels as metadata and codepoints into the
	 * output
	 */
	get_line_embedding_levels(linedata, linelen, get_level_uint32,
	                          set_level_uint32, output, outputsize, true);

	/* determine level range */
	for (i = 0; i < outputlen; i++) {
		level = get_level_uint32(output, i);

		if (level == -1) {
			/* ignored character */
			continue;
		}

		if (level % 2 == 1 && level < min_odd_level) {
			min_odd_level = level;
		}
		if (level > max_level) {
			max_level = level;
		}
	}

	for (level = max_level; level >= min_odd_level /* > 0 */; level--) {
		for (i = 0; i < outputlen; i++) {
			if (get_level_uint32(output, i) >= level) {
				/*
				 * the current character has the desired level
				 */
				first = last = i;

				/* find the end of the level-sequence */
				for (i++; i < outputlen; i++) {
					if (get_level_uint32(output, i) >=
					    level) {
						/* the sequence continues */
						last = i;
					} else {
						break;
					}
				}

				/* invert the sequence first..last respecting
				 * grapheme clusters
				 *
				 * The standard only speaks of combining marks
				 * inversion, but we should in the perfect case
				 * respect _all_ grapheme clusters, which we do
				 * here!
				 */

				/* mark grapheme cluster breaks */
				for (j = first; j <= last;
				     j += grapheme_next_character_break(
					     line + j, outputlen - j)) {
					/*
					 * we use a special trick here: The
					 * first 21 bits of the state are filled
					 * with the codepoint, the next 8 bits
					 * are used for the level, so we can use
					 * the 30th bit to mark the grapheme
					 * cluster breaks. This allows us to
					 * reinvert the grapheme clusters into
					 * the proper direction later.
					 */
					output[j] |= UINT32_C(1) << 29;
				}

				/* global inversion */
				for (k = first, l = last; k < l; k++, l--) {
					/* swap */
					tmp = output[k];
					output[k] = output[l];
					output[l] = tmp;
				}

				/* grapheme cluster reinversion */
#if 0
				for (j = first, laststart = first; j <= last;
				     j++) {
					if (output[j] & (UINT32_C(1) << 29)) {
						/* we hit a mark! given the
						 * grapheme cluster is inverted,
						 * this means that the cluster
						 * ended and we now reinvert it
						 * again
						 */
						for (k = laststart, l = j;
						     k < l; k++, l--) {
							/* swap */
							tmp = output[k];
							output[k] = output[l];
							output[l] = tmp;
						}
						laststart = j + 1;
					}
				}
#endif

				/* unmark grapheme cluster breaks */
				for (j = first; j <= last; j++) {
					output[j] ^= output[j] &
					             UINT32_C(0x20000000);
				}
			}
		}
	}

	/* remove embedding level metadata */
	for (i = 0; i < outputlen; i++) {
		output[i] ^= output[i] & UINT32_C(0x1FE00000);
	}

	return outputlen;
}
