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

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

#[derive(Clone)]
struct CacheEntry {
    time_stamp: usize,
    line_number: usize,
    // 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: Range<BytePos>,
    file: Arc<SourceFile>,
    file_index: usize,
}

impl CacheEntry {
    #[inline]
    fn update(
        &mut self,
        new_file_and_idx: Option<(Arc<SourceFile>, usize)>,
        pos: BytePos,
        time_stamp: usize,
    ) {
        if let Some((file, file_idx)) = new_file_and_idx {
            self.file = file;
            self.file_index = file_idx;
        }

        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);
        self.line_number = line_index + 1;
        self.line = line_bounds;
        self.touch(time_stamp);
    }

    #[inline]
    fn touch(&mut self, time_stamp: usize) {
        self.time_stamp = time_stamp;
    }
}

#[derive(Clone)]
pub struct CachingSourceMapView<'sm> {
    source_map: &'sm SourceMap,
    line_cache: [CacheEntry; 3],
    time_stamp: 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]);
        let entry = CacheEntry {
            time_stamp: 0,
            line_number: 0,
            line: BytePos(0)..BytePos(0),
            file: first_file,
            file_index: 0,
        };

        CachingSourceMapView {
            source_map,
            line_cache: [entry.clone(), entry.clone(), entry],
            time_stamp: 0,
        }
    }

    pub fn byte_pos_to_line_and_col(
        &mut self,
        pos: BytePos,
    ) -> Option<(Arc<SourceFile>, usize, RelativeBytePos)> {
        self.time_stamp += 1;

        // Check if the position is in one of the cached lines
        let cache_idx = self.cache_entry_index(pos);
        if cache_idx != -1 {
            let cache_entry = &mut self.line_cache[cache_idx as usize];
            cache_entry.touch(self.time_stamp);

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

        // No cache hit ...
        let oldest = self.oldest_cache_entry_index();

        // If the entry doesn't point to the correct file, get the new file and index.
        let new_file_and_idx = if !file_contains(&self.line_cache[oldest].file, pos) {
            Some(self.file_for_position(pos)?)
        } else {
            None
        };

        let cache_entry = &mut self.line_cache[oldest];
        cache_entry.update(new_file_and_idx, pos, self.time_stamp);

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

    pub fn span_data_to_lines_and_cols(
        &mut self,
        span_data: &SpanData,
    ) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> {
        self.time_stamp += 1;

        // Check if lo and hi are in the cached lines.
        let lo_cache_idx: isize = self.cache_entry_index(span_data.lo);
        let hi_cache_idx = self.cache_entry_index(span_data.hi);

        if lo_cache_idx != -1 && hi_cache_idx != -1 {
            // Cache hit for span lo and hi. Check if they belong to the same file.
            let lo_file_index = self.line_cache[lo_cache_idx as usize].file_index;
            let hi_file_index = self.line_cache[hi_cache_idx as usize].file_index;

            if lo_file_index != hi_file_index {
                return None;
            }

            self.line_cache[lo_cache_idx as usize].touch(self.time_stamp);
            self.line_cache[hi_cache_idx as usize].touch(self.time_stamp);

            let lo = &self.line_cache[lo_cache_idx as usize];
            let hi = &self.line_cache[hi_cache_idx as usize];
            return Some((
                lo.file.stable_id,
                lo.line_number,
                span_data.lo - lo.line.start,
                hi.line_number,
                span_data.hi - hi.line.start,
            ));
        }

        // No cache hit or cache hit for only one of span lo and hi.
        let oldest = if lo_cache_idx != -1 || hi_cache_idx != -1 {
            let avoid_idx = if lo_cache_idx != -1 { lo_cache_idx } else { hi_cache_idx };
            self.oldest_cache_entry_index_avoid(avoid_idx as usize)
        } else {
            self.oldest_cache_entry_index()
        };

        // If the entry doesn't point to the correct file, get the new file and index.
        // Return early if the file containing beginning of span doesn't contain end of span.
        let new_file_and_idx = if !file_contains(&self.line_cache[oldest].file, span_data.lo) {
            let new_file_and_idx = self.file_for_position(span_data.lo)?;
            if !file_contains(&new_file_and_idx.0, span_data.hi) {
                return None;
            }

            Some(new_file_and_idx)
        } else {
            let file = &self.line_cache[oldest].file;
            if !file_contains(file, span_data.hi) {
                return None;
            }

            None
        };

        // Update the cache entries.
        let (lo_idx, hi_idx) = match (lo_cache_idx, hi_cache_idx) {
            // Oldest cache entry is for span_data.lo line.
            (-1, -1) => {
                let lo = &mut self.line_cache[oldest];
                lo.update(new_file_and_idx, span_data.lo, self.time_stamp);

                if !lo.line.contains(&span_data.hi) {
                    let new_file_and_idx = Some((Arc::clone(&lo.file), lo.file_index));
                    let next_oldest = self.oldest_cache_entry_index_avoid(oldest);
                    let hi = &mut self.line_cache[next_oldest];
                    hi.update(new_file_and_idx, span_data.hi, self.time_stamp);
                    (oldest, next_oldest)
                } else {
                    (oldest, oldest)
                }
            }
            // Oldest cache entry is for span_data.lo line.
            (-1, _) => {
                let lo = &mut self.line_cache[oldest];
                lo.update(new_file_and_idx, span_data.lo, self.time_stamp);
                let hi = &mut self.line_cache[hi_cache_idx as usize];
                hi.touch(self.time_stamp);
                (oldest, hi_cache_idx as usize)
            }
            // Oldest cache entry is for span_data.hi line.
            (_, -1) => {
                let hi = &mut self.line_cache[oldest];
                hi.update(new_file_and_idx, span_data.hi, self.time_stamp);
                let lo = &mut self.line_cache[lo_cache_idx as usize];
                lo.touch(self.time_stamp);
                (lo_cache_idx as usize, oldest)
            }
            _ => {
                panic!(
                    "the case of neither value being equal to -1 was handled above and the function returns."
                );
            }
        };

        let lo = &self.line_cache[lo_idx];
        let hi = &self.line_cache[hi_idx];

        // 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.start);
        assert!(span_data.lo <= lo.line.end);
        assert!(span_data.hi >= hi.line.start);
        assert!(span_data.hi <= hi.line.end);
        assert!(lo.file.contains(span_data.lo));
        assert!(lo.file.contains(span_data.hi));
        assert_eq!(lo.file_index, hi.file_index);

        Some((
            lo.file.stable_id,
            lo.line_number,
            span_data.lo - lo.line.start,
            hi.line_number,
            span_data.hi - hi.line.start,
        ))
    }

    fn cache_entry_index(&self, pos: BytePos) -> isize {
        for (idx, cache_entry) in self.line_cache.iter().enumerate() {
            if cache_entry.line.contains(&pos) {
                return idx as isize;
            }
        }

        -1
    }

    fn oldest_cache_entry_index(&self) -> usize {
        let mut oldest = 0;

        for idx in 1..self.line_cache.len() {
            if self.line_cache[idx].time_stamp < self.line_cache[oldest].time_stamp {
                oldest = idx;
            }
        }

        oldest
    }

    fn oldest_cache_entry_index_avoid(&self, avoid_idx: usize) -> usize {
        let mut oldest = if avoid_idx != 0 { 0 } else { 1 };

        for idx in 0..self.line_cache.len() {
            if idx != avoid_idx
                && self.line_cache[idx].time_stamp < self.line_cache[oldest].time_stamp
            {
                oldest = idx;
            }
        }

        oldest
    }

    fn file_for_position(&self, pos: BytePos) -> Option<(Arc<SourceFile>, usize)> {
        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), file_idx));
            }
        }

        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()
}
