use std::ops::Range;
use std::sync::Arc;

use crate::source_map::SourceMap;
use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData};

/// A `SourceMap` wrapper that caches info about a single recent code position. This gives a good
/// speedup when hashing spans, because often multiple spans within a single line are hashed in
/// succession, and this avoids expensive `SourceMap` lookups each time the cache is hit. We used
/// to cache multiple code positions, but caching a single position ended up being simpler and
/// faster.
#[derive(Clone)]
pub struct CachingSourceMapView<'sm> {
    source_map: &'sm SourceMap,
    file: Arc<SourceFile>,
    // The line's byte position range in the `SourceMap`. This range will fail to contain a valid
    // position in certain edge cases. Spans often start/end one past something, and when that
    // something is the last character of a file (this can happen when a file doesn't end in a
    // newline, for example), we'd still like for the position to be considered within the last
    // line. However, it isn't according to the exclusive upper bound of this range. We cannot
    // change the upper bound to be inclusive, because for most lines, the upper bound is the same
    // as the lower bound of the next line, so there would be an ambiguity.
    //
    // Since the containment aspect of this range is only used to see whether or not the cache
    // entry contains a position, the only ramification of the above is that we will get cache
    // misses for these rare positions. A line lookup for the position via `SourceMap::lookup_line`
    // after a cache miss will produce the last line number, as desired.
    line_bounds: Range<BytePos>,
    line_number: usize,
}

impl<'sm> CachingSourceMapView<'sm> {
    pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
        let files = source_map.files();
        let first_file = Arc::clone(&files[0]);
        CachingSourceMapView {
            source_map,
            file: first_file,
            line_bounds: BytePos(0)..BytePos(0),
            line_number: 0,
        }
    }

    #[inline]
    fn pos_to_line(&self, pos: BytePos) -> (Range<BytePos>, usize) {
        let pos = self.file.relative_position(pos);
        let line_index = self.file.lookup_line(pos).unwrap();
        let line_bounds = self.file.line_bounds(line_index);
        let line_number = line_index + 1;
        (line_bounds, line_number)
    }

    #[inline]
    fn update(&mut self, new_file: Option<Arc<SourceFile>>, pos: BytePos) {
        if let Some(file) = new_file {
            self.file = file;
        }
        (self.line_bounds, self.line_number) = self.pos_to_line(pos);
    }

    pub fn byte_pos_to_line_and_col(
        &mut self,
        pos: BytePos,
    ) -> Option<(Arc<SourceFile>, usize, RelativeBytePos)> {
        if self.line_bounds.contains(&pos) {
            // Cache hit: do nothing.
        } else {
            // Cache miss. If the entry doesn't point to the correct file, get the new file and
            // index.
            let new_file = if !file_contains(&self.file, pos) {
                Some(self.file_for_position(pos)?)
            } else {
                None
            };
            self.update(new_file, pos);
        };

        let col = RelativeBytePos(pos.to_u32() - self.line_bounds.start.to_u32());
        Some((Arc::clone(&self.file), self.line_number, col))
    }

    pub fn span_data_to_lines_and_cols(
        &mut self,
        span_data: &SpanData,
    ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
        let lo_hit = self.line_bounds.contains(&span_data.lo);
        let hi_hit = self.line_bounds.contains(&span_data.hi);
        if lo_hit && hi_hit {
            // span_data.lo and span_data.hi are cached (i.e. both in the same line).
            return Some((
                &self.file,
                self.line_number,
                span_data.lo - self.line_bounds.start,
                self.line_number,
                span_data.hi - self.line_bounds.start,
            ));
        }

        // If the cached file is wrong, update it. Return early if the span lo and hi are in
        // different files.
        let new_file = if !file_contains(&self.file, span_data.lo) {
            let new_file = self.file_for_position(span_data.lo)?;
            if !file_contains(&new_file, span_data.hi) {
                return None;
            }
            Some(new_file)
        } else {
            if !file_contains(&self.file, span_data.hi) {
                return None;
            }
            None
        };

        // If we reach here, lo and hi are in the same file.

        if !lo_hit {
            // We cache the lo information.
            self.update(new_file, span_data.lo);
        }
        let lo_line_bounds = &self.line_bounds;
        let lo_line_number = self.line_number.clone();

        let (hi_line_bounds, hi_line_number) = if !self.line_bounds.contains(&span_data.hi) {
            // hi and lo are in different lines. We compute but don't cache the hi information.
            self.pos_to_line(span_data.hi)
        } else {
            // hi and lo are in the same line.
            (self.line_bounds.clone(), self.line_number)
        };

        // Span lo and hi may equal line end when last line doesn't
        // end in newline, hence the inclusive upper bounds below.
        assert!(span_data.lo >= lo_line_bounds.start);
        assert!(span_data.lo <= lo_line_bounds.end);
        assert!(span_data.hi >= hi_line_bounds.start);
        assert!(span_data.hi <= hi_line_bounds.end);
        assert!(self.file.contains(span_data.lo));
        assert!(self.file.contains(span_data.hi));

        Some((
            &self.file,
            lo_line_number,
            span_data.lo - lo_line_bounds.start,
            hi_line_number,
            span_data.hi,
        ))
    }

    fn file_for_position(&self, pos: BytePos) -> Option<Arc<SourceFile>> {
        if !self.source_map.files().is_empty() {
            let file_idx = self.source_map.lookup_source_file_idx(pos);
            let file = &self.source_map.files()[file_idx];

            if file_contains(file, pos) {
                return Some(Arc::clone(file));
            }
        }

        None
    }
}

#[inline]
fn file_contains(file: &SourceFile, pos: BytePos) -> bool {
    // `SourceMap::lookup_source_file_idx` and `SourceFile::contains` both consider the position
    // one past the end of a file to belong to it. Normally, that's what we want. But for the
    // purposes of converting a byte position to a line and column number, we can't come up with a
    // line and column number if the file is empty, because an empty file doesn't contain any
    // lines. So for our purposes, we don't consider empty files to contain any byte position.
    file.contains(pos) && !file.is_empty()
}
