use super::hb::*;

use std::collections::HashMap;
use std::ffi::c_void;
use std::mem::transmute;
use std::ptr::null_mut;
use std::sync::atomic::{AtomicPtr, AtomicU32, Ordering};
use std::sync::Mutex;

use skrifa::charmap::Charmap;
use skrifa::charmap::MapVariant::Variant;
use skrifa::color::ColorGlyphCollection;
use skrifa::font::FontRef;
use skrifa::instance::{Location, NormalizedCoord, Size};
use skrifa::metrics::GlyphMetrics;
use skrifa::raw::tables::vmtx::Vmtx;
use skrifa::raw::tables::vorg::Vorg;
use skrifa::raw::tables::vvar::Vvar;
use skrifa::raw::TableProvider;
use skrifa::OutlineGlyphCollection;
use skrifa::{GlyphId, GlyphNames, MetadataProvider};

#[cfg(feature = "draw")]
use skrifa::outline::{pen::OutlinePen, DrawSettings};

#[cfg(feature = "paint")]
use skrifa::{
    color::{Brush, ColorPainter, ColorStop, CompositeMode, Extend, Transform},
    metrics::BoundingBox,
    raw::tables::cpal::ColorRecord,
};

// A struct for storing your “fontations” data
#[repr(C)]
struct FontationsData<'a> {
    face_blob: *mut hb_blob_t,
    font: *mut hb_font_t,
    font_ref: FontRef<'a>,
    char_map: Charmap<'a>,
    outline_glyphs: OutlineGlyphCollection<'a>,
    color_glyphs: ColorGlyphCollection<'a>,
    glyph_names: GlyphNames<'a>,
    size: Size,
    vert_metrics: Option<Vmtx<'a>>,
    vert_origin: Option<Vorg<'a>>,
    vert_vars: Option<Vvar<'a>>,

    // Mutex for the below
    mutex: Mutex<()>,
    serial: AtomicU32,
    x_mult: f32,
    y_mult: f32,
    location: Location,
    glyph_metrics: Option<GlyphMetrics<'a>>,
}

impl FontationsData<'_> {
    unsafe fn from_hb_font(font: *mut hb_font_t) -> Option<Self> {
        let face_index = hb_face_get_index(hb_font_get_face(font));
        let face_blob = hb_face_reference_blob(hb_font_get_face(font));
        let blob_length = hb_blob_get_length(face_blob);
        let blob_data = hb_blob_get_data(face_blob, null_mut());
        if blob_data.is_null() {
            return None;
        }
        let face_data = std::slice::from_raw_parts(blob_data as *const u8, blob_length as usize);

        let font_ref = FontRef::from_index(face_data, face_index);
        let font_ref = match font_ref {
            Ok(f) => f,
            Err(_) => return None,
        };

        let char_map = Charmap::new(&font_ref);

        let outline_glyphs = font_ref.outline_glyphs();

        let color_glyphs = font_ref.color_glyphs();

        let glyph_names = font_ref.glyph_names();

        let upem = hb_face_get_upem(hb_font_get_face(font));

        let vert_metrics = font_ref.vmtx().ok();
        let vert_origin = font_ref.vorg().ok();
        let vert_vars = font_ref.vvar().ok();

        let mut data = FontationsData {
            face_blob,
            font,
            font_ref,
            char_map,
            outline_glyphs,
            color_glyphs,
            glyph_names,
            size: Size::new(upem as f32),
            vert_metrics,
            vert_origin,
            vert_vars,
            mutex: Mutex::new(()),
            x_mult: 1.0,
            y_mult: 1.0,
            serial: AtomicU32::new(u32::MAX),
            location: Location::default(),
            glyph_metrics: None,
        };

        data.check_for_updates();

        Some(data)
    }

    unsafe fn _check_for_updates(&mut self) {
        let font_serial = hb_font_get_serial(self.font);
        let serial = self.serial.load(Ordering::Relaxed);
        if serial == font_serial {
            return;
        }

        let _lock = self.mutex.lock().unwrap();

        let mut x_scale: i32 = 0;
        let mut y_scale: i32 = 0;
        hb_font_get_scale(self.font, &mut x_scale, &mut y_scale);
        let upem = hb_face_get_upem(hb_font_get_face(self.font));
        self.x_mult = x_scale as f32 / upem as f32;
        self.y_mult = y_scale as f32 / upem as f32;

        let mut num_coords: u32 = 0;
        let coords = hb_font_get_var_coords_normalized(self.font, &mut num_coords);
        let coords = if coords.is_null() {
            &[]
        } else {
            std::slice::from_raw_parts(coords, num_coords as usize)
        };
        let all_zeros = coords.iter().all(|&x| x == 0);
        // if all zeros, use Location::default()
        // otherwise, use the provided coords.
        // This currently doesn't seem to have a perf effect on fontations, but it's a good idea to
        // check if the coords are all zeros before creating a Location.
        self.location = if all_zeros {
            Location::default()
        } else {
            let mut location = Location::new(num_coords as usize);
            let coords_mut = location.coords_mut();
            coords_mut
                .iter_mut()
                .zip(coords.iter().map(|v| NormalizedCoord::from_bits(*v as i16)))
                .for_each(|(dest, source)| *dest = source);
            location
        };

        let location = transmute::<&Location, &Location>(&self.location);
        self.glyph_metrics = Some(self.font_ref.glyph_metrics(self.size, location));

        self.serial.store(font_serial, Ordering::Release);
    }
    fn check_for_updates(&mut self) {
        unsafe { self._check_for_updates() }
    }
}

extern "C" fn _hb_fontations_data_destroy(font_data: *mut c_void) {
    let data = unsafe { Box::from_raw(font_data as *mut FontationsData) };

    unsafe {
        hb_blob_destroy(data.face_blob);
    }
}

fn struct_at_offset<T: Copy>(first: *const T, index: u32, stride: u32) -> T {
    unsafe { *((first as *const u8).offset((index * stride) as isize) as *const T) }
}

fn struct_at_offset_mut<T: Copy>(first: *mut T, index: u32, stride: u32) -> &'static mut T {
    unsafe { &mut *((first as *mut u8).offset((index * stride) as isize) as *mut T) }
}

extern "C" fn _hb_fontations_get_nominal_glyphs(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    count: ::std::os::raw::c_uint,
    first_unicode: *const hb_codepoint_t,
    unicode_stride: ::std::os::raw::c_uint,
    first_glyph: *mut hb_codepoint_t,
    glyph_stride: ::std::os::raw::c_uint,
    _user_data: *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_uint {
    let data = unsafe { &*(font_data as *const FontationsData) };
    let char_map = &data.char_map;

    for i in 0..count {
        let unicode = struct_at_offset(first_unicode, i, unicode_stride);
        let Some(glyph) = char_map.map(unicode) else {
            return i;
        };
        let glyph_id = glyph.to_u32() as hb_codepoint_t;
        *struct_at_offset_mut(first_glyph, i, glyph_stride) = glyph_id;
    }

    count
}
extern "C" fn _hb_fontations_get_variation_glyph(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    unicode: hb_codepoint_t,
    variation_selector: hb_codepoint_t,
    glyph: *mut hb_codepoint_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &*(font_data as *const FontationsData) };

    let char_map = &data.char_map;

    match char_map.map_variant(unicode, variation_selector) {
        Some(Variant(glyph_id)) => {
            unsafe { *glyph = glyph_id.to_u32() as hb_codepoint_t };
            true as hb_bool_t
        }
        _ => false as hb_bool_t,
    }
}

extern "C" fn _hb_fontations_get_glyph_h_advances(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    count: ::std::os::raw::c_uint,
    first_glyph: *const hb_codepoint_t,
    glyph_stride: ::std::os::raw::c_uint,
    first_advance: *mut hb_position_t,
    advance_stride: ::std::os::raw::c_uint,
    _user_data: *mut ::std::os::raw::c_void,
) {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    let glyph_metrics = &data.glyph_metrics.as_ref().unwrap();

    for i in 0..count {
        let glyph = struct_at_offset(first_glyph, i, glyph_stride);
        let glyph_id = GlyphId::new(glyph);
        let advance = glyph_metrics.advance_width(glyph_id).unwrap_or_default();
        let scaled = (advance * data.x_mult).round() as hb_position_t;
        *struct_at_offset_mut(first_advance, i, advance_stride) = scaled;
    }
}

extern "C" fn _hb_fontations_get_glyph_v_advances(
    font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    count: ::std::os::raw::c_uint,
    first_glyph: *const hb_codepoint_t,
    glyph_stride: ::std::os::raw::c_uint,
    first_advance: *mut hb_position_t,
    advance_stride: ::std::os::raw::c_uint,
    _user_data: *mut ::std::os::raw::c_void,
) {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    if let Some(vert_metrics) = &data.vert_metrics {
        let vert_vars = &data.vert_vars;
        for i in 0..count {
            let glyph = struct_at_offset(first_glyph, i, glyph_stride);
            let glyph_id = GlyphId::new(glyph);
            let mut advance = vert_metrics.advance(glyph_id).unwrap_or_default() as f32;
            if let Some(vert_vars) = vert_vars {
                let coords = data.location.coords();
                if !coords.is_empty() {
                    advance += vert_vars
                        .advance_height_delta(glyph_id, coords)
                        .unwrap_or_default()
                        .to_f32();
                }
            }
            let scaled = -(advance * data.y_mult).round() as hb_position_t;
            *struct_at_offset_mut(first_advance, i, advance_stride) = scaled;
        }
    } else {
        let mut font_extents = unsafe { std::mem::zeroed() };
        unsafe {
            hb_font_get_extents_for_direction(
                font,
                hb_direction_t_HB_DIRECTION_LTR,
                &mut font_extents,
            );
        }
        let advance: hb_position_t = -(font_extents.ascender - font_extents.descender);

        for i in 0..count {
            *struct_at_offset_mut(first_advance, i, advance_stride) = advance;
        }
    }
}

extern "C" fn _hb_fontations_get_glyph_v_origin(
    font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    glyph: hb_codepoint_t,
    x: *mut hb_position_t,
    y: *mut hb_position_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    unsafe {
        *x = hb_font_get_glyph_h_advance(font, glyph) / 2;
    }

    let vert_origin = &data.vert_origin;
    if let Some(vert_origin) = vert_origin {
        let glyph_id = GlyphId::new(glyph);

        let mut y_origin = vert_origin.vertical_origin_y(glyph_id) as f32;
        let vert_vars = &data.vert_vars;
        if let Some(vert_vars) = vert_vars {
            let coords = data.location.coords();
            if !coords.is_empty() {
                y_origin += vert_vars
                    .v_org_delta(glyph_id, coords)
                    .unwrap_or_default()
                    .to_f32();
            }
        }

        unsafe {
            *y = (y_origin * data.y_mult).round() as hb_position_t;
        }

        return true as hb_bool_t;
    }

    let mut extents: hb_glyph_extents_t = unsafe { std::mem::zeroed() };
    if unsafe { hb_font_get_glyph_extents(font, glyph, &mut extents) != 0 } {
        if let Some(vert_metrics) = &data.vert_metrics {
            let glyph = GlyphId::new(glyph);
            let mut tsb: f32 = vert_metrics.side_bearing(glyph).unwrap_or_default() as f32;
            if let Some(vert_vars) = &data.vert_vars {
                let coords = data.location.coords();
                if !coords.is_empty() {
                    tsb += vert_vars
                        .tsb_delta(glyph, coords)
                        .unwrap_or_default()
                        .to_f32();
                }
            }
            unsafe {
                *y = extents.y_bearing + (tsb * data.y_mult).round() as hb_position_t;
            }
            return true as hb_bool_t;
        }

        let mut font_extents: hb_font_extents_t = unsafe { std::mem::zeroed() };
        unsafe {
            hb_font_get_extents_for_direction(
                font,
                hb_direction_t_HB_DIRECTION_LTR,
                &mut font_extents,
            );
        }
        let advance: hb_position_t = font_extents.ascender - font_extents.descender;
        let diff: hb_position_t = advance - -extents.height;
        unsafe {
            *y = extents.y_bearing + (diff >> 1);
        }
        return true as hb_bool_t;
    }

    let mut font_extents: hb_font_extents_t = unsafe { std::mem::zeroed() };
    unsafe {
        hb_font_get_extents_for_direction(font, hb_direction_t_HB_DIRECTION_LTR, &mut font_extents);
    }
    unsafe {
        *y = font_extents.ascender;
    }

    true as hb_bool_t
}

extern "C" fn _hb_fontations_get_glyph_extents(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    glyph: hb_codepoint_t,
    extents: *mut hb_glyph_extents_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    let glyph_id = GlyphId::new(glyph);

    // COLRv1 color glyphs are not supported by glyph_metrics.
    let color_glyphs = &data.color_glyphs;
    if color_glyphs.get(glyph_id).is_some() {
        return false as hb_bool_t;
    };

    let glyph_metrics = &data.glyph_metrics.as_ref().unwrap();
    let Some(glyph_extents) = glyph_metrics.bounds(glyph_id) else {
        return false as hb_bool_t;
    };

    let x_bearing = (glyph_extents.x_min * data.x_mult).round() as hb_position_t;
    let width = (glyph_extents.x_max * data.x_mult).round() as hb_position_t - x_bearing;
    let y_bearing = (glyph_extents.y_max * data.y_mult).round() as hb_position_t;
    let height = (glyph_extents.y_min * data.y_mult).round() as hb_position_t - y_bearing;

    unsafe {
        *extents = hb_glyph_extents_t {
            x_bearing,
            y_bearing,
            width,
            height,
        };
    }

    true as hb_bool_t
}

extern "C" fn _hb_fontations_get_font_h_extents(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    extents: *mut hb_font_extents_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    let font_ref = &data.font_ref;
    let size = &data.size;
    let location = &data.location;
    let metrics = font_ref.metrics(*size, location);

    unsafe {
        (*extents).ascender = (metrics.ascent * data.y_mult).round() as hb_position_t;
        (*extents).descender = (metrics.descent * data.y_mult).round() as hb_position_t;
        (*extents).line_gap = (metrics.leading * data.y_mult).round() as hb_position_t;
    }

    true as hb_bool_t
}

#[cfg(feature = "draw")]
struct HbPen {
    x_mult: f32,
    y_mult: f32,
    draw_state: *mut hb_draw_state_t,
    draw_funcs: *mut hb_draw_funcs_t,
    draw_data: *mut c_void,
}

#[cfg(feature = "draw")]
impl OutlinePen for HbPen {
    fn move_to(&mut self, x: f32, y: f32) {
        unsafe {
            hb_draw_move_to(
                self.draw_funcs,
                self.draw_data,
                self.draw_state,
                x * self.x_mult,
                y * self.y_mult,
            );
        }
    }
    fn line_to(&mut self, x: f32, y: f32) {
        unsafe {
            hb_draw_line_to(
                self.draw_funcs,
                self.draw_data,
                self.draw_state,
                x * self.x_mult,
                y * self.y_mult,
            );
        }
    }
    fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
        unsafe {
            hb_draw_quadratic_to(
                self.draw_funcs,
                self.draw_data,
                self.draw_state,
                x1 * self.x_mult,
                y1 * self.y_mult,
                x * self.x_mult,
                y * self.y_mult,
            );
        }
    }
    fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
        unsafe {
            hb_draw_cubic_to(
                self.draw_funcs,
                self.draw_data,
                self.draw_state,
                x1 * self.x_mult,
                y1 * self.y_mult,
                x2 * self.x_mult,
                y2 * self.y_mult,
                x * self.x_mult,
                y * self.y_mult,
            );
        }
    }
    fn close(&mut self) {
        unsafe {
            hb_draw_close_path(self.draw_funcs, self.draw_data, self.draw_state);
        }
    }
}

#[cfg(feature = "draw")]
extern "C" fn _hb_fontations_draw_glyph_or_fail(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    glyph: hb_codepoint_t,
    draw_funcs: *mut hb_draw_funcs_t,
    draw_data: *mut ::std::os::raw::c_void,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    let size = &data.size;
    let location = &data.location;
    let outline_glyphs = &data.outline_glyphs;

    let glyph_id = GlyphId::new(glyph);
    let Some(outline_glyph) = outline_glyphs.get(glyph_id) else {
        return false as hb_bool_t;
    };
    let draw_settings = DrawSettings::unhinted(*size, location);

    let mut draw_state = unsafe { std::mem::zeroed::<hb_draw_state_t>() };

    let mut pen = HbPen {
        x_mult: data.x_mult,
        y_mult: data.y_mult,
        draw_state: &mut draw_state,
        draw_funcs,
        draw_data,
    };

    let _ = outline_glyph.draw(draw_settings, &mut pen);
    true as hb_bool_t
}

#[cfg(feature = "paint")]
struct HbColorPainter<'a> {
    font: *mut hb_font_t,
    paint_funcs: *mut hb_paint_funcs_t,
    paint_data: *mut c_void,
    color_records: &'a [ColorRecord],
    foreground: hb_color_t,
    is_glyph_clip: u64,
    clip_depth: u32,
}

#[cfg(feature = "paint")]
impl HbColorPainter<'_> {
    fn lookup_color(&self, color_index: u16, alpha: f32) -> hb_color_t {
        if color_index == 0xFFFF {
            // Apply alpha to foreground color
            return ((self.foreground & 0xFFFFFF00)
                | (((self.foreground & 0xFF) as f32 * alpha).round() as u32))
                as hb_color_t;
        }

        let c = self.color_records.get(color_index as usize);
        if let Some(c) = c {
            (((c.blue as u32) << 24)
                | ((c.green as u32) << 16)
                | ((c.red as u32) << 8)
                | ((c.alpha as f32 * alpha).round() as u32)) as hb_color_t
        } else {
            0 as hb_color_t
        }
    }

    fn make_color_line(&self, color_line: &ColorLineData) -> hb_color_line_t {
        let mut cl = unsafe { std::mem::zeroed::<hb_color_line_t>() };
        cl.data = color_line as *const ColorLineData as *mut ::std::os::raw::c_void;
        cl.get_color_stops = Some(_hb_fontations_get_color_stops);
        cl.get_extend = Some(_hb_fontations_get_extend);
        cl
    }
}

#[cfg(feature = "paint")]
struct ColorLineData<'a> {
    painter: &'a HbColorPainter<'a>,
    color_stops: &'a [ColorStop],
    extend: Extend,
}
#[cfg(feature = "paint")]
extern "C" fn _hb_fontations_get_color_stops(
    _color_line: *mut hb_color_line_t,
    color_line_data: *mut ::std::os::raw::c_void,
    start: ::std::os::raw::c_uint,
    count_out: *mut ::std::os::raw::c_uint,
    color_stops_out: *mut hb_color_stop_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_uint {
    let color_line_data = unsafe { &*(color_line_data as *const ColorLineData) };
    let color_stops = &color_line_data.color_stops;
    if count_out.is_null() {
        return color_stops.len() as u32;
    }
    let count = unsafe { *count_out };
    for i in 0..count {
        let Some(stop) = color_stops.get(start as usize + i as usize) else {
            unsafe {
                *count_out = i;
            };
            break;
        };
        unsafe {
            *(color_stops_out.offset(i as isize)) = hb_color_stop_t {
                offset: stop.offset,
                color: color_line_data
                    .painter
                    .lookup_color(stop.palette_index, stop.alpha),
                is_foreground: (stop.palette_index == 0xFFFF) as hb_bool_t,
            };
        }
    }
    color_stops.len() as u32
}
#[cfg(feature = "paint")]
extern "C" fn _hb_fontations_get_extend(
    _color_line: *mut hb_color_line_t,
    color_line_data: *mut ::std::os::raw::c_void,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_paint_extend_t {
    let color_line_data = unsafe { &*(color_line_data as *const ColorLineData) };
    color_line_data.extend as hb_paint_extend_t // They are the same
}

#[cfg(feature = "paint")]
pub fn _hb_fontations_unreduce_anchors(
    x0: f32,
    y0: f32,
    x1: f32,
    y1: f32,
) -> (f32, f32, f32, f32, f32, f32) {
    /* Returns (x0, y0, x1, y1, x2, y2) such that the original
     * `_hb_cairo_reduce_anchors` would produce (xx0, yy0, xx1, yy1)
     * as outputs.
     * The OT spec has the following wording; we just need to
     * invert that operation here:
     *
     * Note: An implementation can derive a single vector, from p₀ to a point p₃, by computing the
     * orthogonal projection of the vector from p₀ to p₁ onto a line perpendicular to line p₀p₂ and
     * passing through p₀ to obtain point p₃. The linear gradient defined using p₀, p₁ and p₂ as
     * described above is functionally equivalent to a linear gradient defined by aligning stop
     * offset 0 to p₀ and aligning stop offset 1.0 to p₃, with each color projecting on either side
     * of that line in a perpendicular direction. This specification uses three points, p₀, p₁ and
     * p₂, as that provides greater flexibility in controlling the placement and rotation of the
     * gradient, as well as variations thereof.
     */

    let dx = x1 - x0;
    let dy = y1 - y0;

    (x0, y0, x1, y1, x0 + dy, y0 - dx)
}

#[cfg(feature = "paint")]
impl ColorPainter for HbColorPainter<'_> {
    fn push_transform(&mut self, transform: Transform) {
        unsafe {
            hb_paint_push_transform(
                self.paint_funcs,
                self.paint_data,
                transform.xx,
                transform.yx,
                transform.xy,
                transform.yy,
                transform.dx,
                transform.dy,
            );
        }
    }
    fn pop_transform(&mut self) {
        unsafe {
            hb_paint_pop_transform(self.paint_funcs, self.paint_data);
        }
    }
    fn fill_glyph(
        &mut self,
        glyph_id: GlyphId,
        brush_transform: Option<Transform>,
        brush: Brush<'_>,
    ) {
        unsafe {
            hb_paint_push_inverse_font_transform(self.paint_funcs, self.paint_data, self.font);
            hb_paint_push_clip_glyph(
                self.paint_funcs,
                self.paint_data,
                glyph_id.to_u32() as hb_codepoint_t,
                self.font,
            );
            hb_paint_push_font_transform(self.paint_funcs, self.paint_data, self.font);
        }
        if let Some(wrap_in_transform) = brush_transform {
            self.push_transform(wrap_in_transform);
            self.fill(brush);
            self.pop_transform();
        } else {
            self.fill(brush);
        }
        self.pop_transform();
        unsafe {
            hb_paint_pop_clip(self.paint_funcs, self.paint_data);
        }
        self.pop_transform();
    }
    fn push_clip_glyph(&mut self, glyph_id: GlyphId) {
        if self.clip_depth < 64 {
            self.is_glyph_clip |= 1 << self.clip_depth;
            self.clip_depth += 1;
        } else {
            return;
        }
        unsafe {
            hb_paint_push_inverse_font_transform(self.paint_funcs, self.paint_data, self.font);
            hb_paint_push_clip_glyph(
                self.paint_funcs,
                self.paint_data,
                glyph_id.to_u32() as hb_codepoint_t,
                self.font,
            );
            hb_paint_push_font_transform(self.paint_funcs, self.paint_data, self.font);
        }
    }
    fn push_clip_box(&mut self, bbox: BoundingBox) {
        if self.clip_depth < 64 {
            self.is_glyph_clip &= !(1 << self.clip_depth);
            self.clip_depth += 1;
        } else {
            return;
        }
        unsafe {
            hb_paint_push_clip_rectangle(
                self.paint_funcs,
                self.paint_data,
                bbox.x_min,
                bbox.y_min,
                bbox.x_max,
                bbox.y_max,
            );
        }
    }
    fn pop_clip(&mut self) {
        if self.clip_depth > 0 {
            self.clip_depth -= 1;
        } else {
            return;
        }
        unsafe {
            if (self.is_glyph_clip & (1 << self.clip_depth)) != 0 {
                hb_paint_pop_transform(self.paint_funcs, self.paint_data);
            }
            hb_paint_pop_clip(self.paint_funcs, self.paint_data);
            if (self.is_glyph_clip & (1 << self.clip_depth)) != 0 {
                hb_paint_pop_transform(self.paint_funcs, self.paint_data);
            }
        }
    }
    fn fill(&mut self, brush: Brush) {
        match brush {
            Brush::Solid {
                palette_index: color_index,
                alpha,
            } => {
                let is_foreground = color_index == 0xFFFF;
                unsafe {
                    hb_paint_color(
                        self.paint_funcs,
                        self.paint_data,
                        is_foreground as hb_bool_t,
                        self.lookup_color(color_index, alpha),
                    );
                }
            }
            Brush::LinearGradient {
                color_stops,
                extend,
                p0,
                p1,
            } => {
                let color_stops = ColorLineData {
                    painter: self,
                    color_stops,
                    extend,
                };
                let mut color_line = self.make_color_line(&color_stops);

                let (x0, y0, x1, y1, x2, y2) =
                    _hb_fontations_unreduce_anchors(p0.x, p0.y, p1.x, p1.y);

                unsafe {
                    hb_paint_linear_gradient(
                        self.paint_funcs,
                        self.paint_data,
                        &mut color_line,
                        x0,
                        y0,
                        x1,
                        y1,
                        x2,
                        y2,
                    );
                }
            }
            Brush::RadialGradient {
                color_stops,
                extend,
                c0,
                r0,
                c1,
                r1,
            } => {
                let color_stops = ColorLineData {
                    painter: self,
                    color_stops,
                    extend,
                };
                let mut color_line = self.make_color_line(&color_stops);
                unsafe {
                    hb_paint_radial_gradient(
                        self.paint_funcs,
                        self.paint_data,
                        &mut color_line,
                        c0.x,
                        c0.y,
                        r0,
                        c1.x,
                        c1.y,
                        r1,
                    );
                }
            }
            Brush::SweepGradient {
                color_stops,
                extend,
                c0,
                start_angle,
                end_angle,
            } => {
                let color_stops = ColorLineData {
                    painter: self,
                    color_stops,
                    extend,
                };
                let mut color_line = self.make_color_line(&color_stops);
                // Skrifa has this gem, so we swap end_angle and start_angle
                // when passing to our API:
                //
                //  * Convert angles and stops from counter-clockwise to clockwise
                //  * for the shader if the gradient is not already reversed due to
                //  * start angle being larger than end angle.
                //
                //  Undo that.
                let (start_angle, end_angle) = (360. - start_angle, 360. - end_angle);
                let start_angle = start_angle.to_radians();
                let end_angle = end_angle.to_radians();
                unsafe {
                    hb_paint_sweep_gradient(
                        self.paint_funcs,
                        self.paint_data,
                        &mut color_line,
                        c0.x,
                        c0.y,
                        start_angle,
                        end_angle,
                    );
                }
            }
        }
    }
    fn push_layer(&mut self, mode: CompositeMode) {
        let mode = mode as hb_paint_composite_mode_t;
        unsafe {
            hb_paint_push_group_for(self.paint_funcs, self.paint_data, mode);
        }
    }
    fn pop_layer_with_mode(&mut self, mode: CompositeMode) {
        let mode = mode as hb_paint_composite_mode_t; // They are the same
        unsafe {
            hb_paint_pop_group(self.paint_funcs, self.paint_data, mode);
        }
    }
}

#[cfg(feature = "paint")]
extern "C" fn _hb_fontations_paint_glyph_or_fail(
    font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    glyph: hb_codepoint_t,
    paint_funcs: *mut hb_paint_funcs_t,
    paint_data: *mut ::std::os::raw::c_void,
    palette_index: ::std::os::raw::c_uint,
    foreground: hb_color_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };
    data.check_for_updates();

    let font_ref = &data.font_ref;
    let location = &data.location;
    let color_glyphs = &data.color_glyphs;

    let glyph_id = GlyphId::new(glyph);
    let Some(color_glyph) = color_glyphs.get(glyph_id) else {
        return false as hb_bool_t;
    };

    let cpal = font_ref.cpal();
    let color_records = if let Ok(cpal) = cpal {
        let num_entries = cpal.num_palette_entries().into();
        let color_records = cpal.color_records_array();
        let start_index = cpal
            .color_record_indices()
            .get(palette_index as usize)
            .or_else(|| {
                // https://github.com/harfbuzz/harfbuzz/issues/5116
                cpal.color_record_indices().first()
            });

        if let (Some(Ok(color_records)), Some(start_index)) = (color_records, start_index) {
            let start_index: usize = start_index.get().into();
            let color_records = &color_records[start_index..start_index + num_entries];
            unsafe { std::slice::from_raw_parts(color_records.as_ptr(), num_entries) }
        } else {
            &[]
        }
    } else {
        &[]
    };

    let font = if (unsafe { hb_font_is_synthetic(font) } != false as hb_bool_t) {
        unsafe {
            let sub_font = hb_font_create_sub_font(font);
            hb_font_set_synthetic_bold(sub_font, 0.0, 0.0, true as hb_bool_t);
            hb_font_set_synthetic_slant(sub_font, 0.0);
            sub_font
        }
    } else {
        unsafe { hb_font_reference(font) }
    };

    let mut painter = HbColorPainter {
        font,
        paint_funcs,
        paint_data,
        color_records,
        foreground,
        is_glyph_clip: 0,
        clip_depth: 0,
    };
    unsafe {
        hb_paint_push_font_transform(paint_funcs, paint_data, font);
    }
    let _ = color_glyph.paint(location, &mut painter);
    unsafe {
        hb_paint_pop_transform(paint_funcs, paint_data);
        hb_font_destroy(font);
    }
    true as hb_bool_t
}

extern "C" fn _hb_fontations_glyph_name(
    _font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    glyph: hb_codepoint_t,
    name: *mut ::std::os::raw::c_char,
    size: ::std::os::raw::c_uint,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &mut *(font_data as *mut FontationsData) };

    if let Some(glyph_name) = data.glyph_names.get(GlyphId::new(glyph)) {
        if size == 0 {
            return true as hb_bool_t;
        }
        let glyph_name = glyph_name.as_str();
        // Copy the glyph name into the buffer, up to size-1 bytes
        let len = glyph_name.len().min((size as usize) - 1);
        unsafe {
            std::slice::from_raw_parts_mut(name as *mut u8, len)
                .copy_from_slice(&glyph_name.as_bytes()[..len]);
            *name.add(len) = 0;
        }
        true as hb_bool_t
    } else {
        false as hb_bool_t
    }
}

static mut GLYPH_FROM_NAMES_KEY: hb_user_data_key_t = hb_user_data_key_t { unused: 0 };

extern "C" fn _hb_glyph_from_names_destroy(data: *mut c_void) {
    let _ = unsafe { Box::from_raw(data as *mut HashMap<String, u32>) };
}

extern "C" fn _hb_fontations_glyph_from_name(
    font: *mut hb_font_t,
    font_data: *mut ::std::os::raw::c_void,
    name: *const ::std::os::raw::c_char,
    len: ::std::os::raw::c_int,
    glyph: *mut hb_codepoint_t,
    _user_data: *mut ::std::os::raw::c_void,
) -> hb_bool_t {
    let data = unsafe { &*(font_data as *const FontationsData) };

    // SAFETY: HarfBuzz guarantees the string is valid memory for `len` bytes.
    let name_bytes = unsafe { std::slice::from_raw_parts(name as *const u8, len as usize) };
    let name_str = match std::str::from_utf8(name_bytes) {
        Ok(s) => s,
        Err(_) => return false as hb_bool_t,
    };

    let face = unsafe { hb_font_get_face(font) };
    let mut user_data_ptr: *mut c_void;

    loop {
        user_data_ptr =
            unsafe { hb_face_get_user_data(face, std::ptr::addr_of_mut!(GLYPH_FROM_NAMES_KEY)) };
        if !user_data_ptr.is_null() {
            break;
        }

        // Build the HashMap from glyph names to IDs
        let mut map = HashMap::new();
        for (glyph_id, glyph_name) in data.glyph_names.iter() {
            map.insert(glyph_name.to_string(), glyph_id.to_u32());
        }

        let boxed_map = Box::new(map);
        let ptr = Box::into_raw(boxed_map) as *mut c_void;

        let success = unsafe {
            hb_face_set_user_data(
                face,
                std::ptr::addr_of_mut!(GLYPH_FROM_NAMES_KEY),
                ptr,
                Some(_hb_glyph_from_names_destroy),
                true as hb_bool_t,
            )
        };

        if success != false as hb_bool_t {
            user_data_ptr = ptr;
            break;
        }

        // We failed to set user data — reclaim the pointer to avoid leaking
        _hb_glyph_from_names_destroy(ptr);
        // Try again in next loop iteration
    }

    let glyph_from_names = unsafe { &*(user_data_ptr as *const HashMap<String, u32>) };

    match glyph_from_names.get(name_str) {
        Some(gid) => {
            unsafe { *glyph = *gid };
            true as hb_bool_t
        }
        None => false as hb_bool_t,
    }
}

fn _hb_fontations_font_funcs_get() -> *mut hb_font_funcs_t {
    static STATIC_FFUNCS: AtomicPtr<hb_font_funcs_t> = AtomicPtr::new(null_mut());

    loop {
        let mut ffuncs = STATIC_FFUNCS.load(Ordering::Acquire);

        if !ffuncs.is_null() {
            return ffuncs;
        }

        ffuncs = unsafe { hb_font_funcs_create() };

        unsafe {
            hb_font_funcs_set_nominal_glyphs_func(
                ffuncs,
                Some(_hb_fontations_get_nominal_glyphs),
                null_mut(),
                None,
            );
            hb_font_funcs_set_variation_glyph_func(
                ffuncs,
                Some(_hb_fontations_get_variation_glyph),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_h_advances_func(
                ffuncs,
                Some(_hb_fontations_get_glyph_h_advances),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_v_advances_func(
                ffuncs,
                Some(_hb_fontations_get_glyph_v_advances),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_v_origin_func(
                ffuncs,
                Some(_hb_fontations_get_glyph_v_origin),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_extents_func(
                ffuncs,
                Some(_hb_fontations_get_glyph_extents),
                null_mut(),
                None,
            );
            hb_font_funcs_set_font_h_extents_func(
                ffuncs,
                Some(_hb_fontations_get_font_h_extents),
                null_mut(),
                None,
            );
            #[cfg(feature = "draw")]
            hb_font_funcs_set_draw_glyph_or_fail_func(
                ffuncs,
                Some(_hb_fontations_draw_glyph_or_fail),
                null_mut(),
                None,
            );
            #[cfg(feature = "paint")]
            hb_font_funcs_set_paint_glyph_or_fail_func(
                ffuncs,
                Some(_hb_fontations_paint_glyph_or_fail),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_name_func(
                ffuncs,
                Some(_hb_fontations_glyph_name),
                null_mut(),
                None,
            );
            hb_font_funcs_set_glyph_from_name_func(
                ffuncs,
                Some(_hb_fontations_glyph_from_name),
                null_mut(),
                None,
            );
        }

        if (STATIC_FFUNCS.compare_exchange(null_mut(), ffuncs, Ordering::SeqCst, Ordering::Relaxed))
            == Ok(null_mut())
        {
            return ffuncs;
        } else {
            unsafe {
                hb_font_funcs_destroy(ffuncs);
            }
        }
    }
}

/// # Safety
///
/// This function is unsafe because it connects with the HarfBuzz API.
#[no_mangle]
pub unsafe extern "C" fn hb_fontations_font_set_funcs(font: *mut hb_font_t) {
    let ffuncs = _hb_fontations_font_funcs_get();

    let data = FontationsData::from_hb_font(font);
    let data = match data {
        Some(d) => d,
        None => return,
    };
    let data_ptr = Box::into_raw(Box::new(data)) as *mut c_void;

    hb_font_set_funcs(font, ffuncs, data_ptr, Some(_hb_fontations_data_destroy));
}
