{-# LANGUAGE NoImplicitPrelude #-}

module Data.Aviation.Casa.AbbreviationsAndAcronyms.Search(
  all_Acronym_name_index
, all_Acronym_meaning_index
, all_Acronym_source_index
, searchIndexName
, searchIndexMeaning
, searchIndexSource
, searchIndexNameSource
, searchIndexNameMeaning
, searchIndexMeaningSource
, searchIndexNameMeaningSource
, searchFuzzyName
, searchFuzzyMeaning
, searchFuzzySource
, searchFuzzyNameMeaning
, searchFuzzyNameSource
, searchFuzzyMeaningSource
, searchFuzzyNameMeaningSource
) where

import Control.Applicative((<|>))
import Control.Category((.))
import Control.Lens((^.))
import Data.Aviation.Casa.AbbreviationsAndAcronyms.Acronym(Acronym(Acronym), allAcronyms, name, meaning, source)
import Data.Bool(Bool)
import Data.Char(isAlpha, toUpper)
import Data.Foldable(foldl')
import Data.Function(($))
import Data.Functor((<$>), fmap)
import Data.List(sortBy, filter)
import Data.Map(Map)
import qualified Data.Map as Map(fromList, fromListWith, lookup, insertWith, toList)
import Data.Maybe(Maybe(Just, Nothing))
import Data.Ord(Ord((>)), compare)
import Data.Semigroup((<>))
import Data.String(String)
import Data.Monoid.Textual(TextualMonoid)
import qualified Text.Fuzzy as Fuzzy(filter, score)
import Text.Fuzzy(Fuzzy(Fuzzy))
import Data.List.NonEmpty(NonEmpty((:|)))

all_Acronym_name_index ::
  Map String (NonEmpty (String, String))
all_Acronym_name_index :: Map String (NonEmpty (String, String))
all_Acronym_name_index =
  (NonEmpty (String, String)
 -> NonEmpty (String, String) -> NonEmpty (String, String))
-> [(String, NonEmpty (String, String))]
-> Map String (NonEmpty (String, String))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith NonEmpty (String, String)
-> NonEmpty (String, String) -> NonEmpty (String, String)
forall a. Semigroup a => a -> a -> a
(<>) (((\(Acronym String
_name String
_meaning String
_src) -> (String
_name, (String
_meaning, String
_src) (String, String) -> [(String, String)] -> NonEmpty (String, String)
forall a. a -> [a] -> NonEmpty a
:| [])) (Acronym -> (String, NonEmpty (String, String)))
-> [Acronym] -> [(String, NonEmpty (String, String))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Acronym]
allAcronyms))

all_Acronym_meaning_index ::
  Map String (NonEmpty (String, String))
all_Acronym_meaning_index :: Map String (NonEmpty (String, String))
all_Acronym_meaning_index =
  (NonEmpty (String, String)
 -> NonEmpty (String, String) -> NonEmpty (String, String))
-> [(String, NonEmpty (String, String))]
-> Map String (NonEmpty (String, String))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith NonEmpty (String, String)
-> NonEmpty (String, String) -> NonEmpty (String, String)
forall a. Semigroup a => a -> a -> a
(<>) (((\(Acronym String
_name String
_meaning String
_src) -> (String
_meaning, (String
_name, String
_src) (String, String) -> [(String, String)] -> NonEmpty (String, String)
forall a. a -> [a] -> NonEmpty a
:| [])) (Acronym -> (String, NonEmpty (String, String)))
-> [Acronym] -> [(String, NonEmpty (String, String))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Acronym]
allAcronyms))

all_Acronym_source_index ::
  Map String (NonEmpty (String, String))
all_Acronym_source_index :: Map String (NonEmpty (String, String))
all_Acronym_source_index =
  (NonEmpty (String, String)
 -> NonEmpty (String, String) -> NonEmpty (String, String))
-> [(String, NonEmpty (String, String))]
-> Map String (NonEmpty (String, String))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith NonEmpty (String, String)
-> NonEmpty (String, String) -> NonEmpty (String, String)
forall a. Semigroup a => a -> a -> a
(<>) (((\(Acronym String
_name String
_meaning String
_src) -> (String
_src, (String
_name, String
_meaning) (String, String) -> [(String, String)] -> NonEmpty (String, String)
forall a. a -> [a] -> NonEmpty a
:| [])) (Acronym -> (String, NonEmpty (String, String)))
-> [Acronym] -> [(String, NonEmpty (String, String))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Acronym]
allAcronyms))

searchIndexName ::
  String
  -> [Acronym]
searchIndexName :: String -> [Acronym]
searchIndexName String
s =
  let s' :: String
s' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAlpha (String -> String) -> (String -> String) -> String -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Char -> Char) -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toUpper (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
s
  in  Maybe (NonEmpty Acronym) -> [Acronym]
forall a. Maybe (NonEmpty a) -> [a]
maybeNE (((\(String
_meaning, String
_src) -> String -> String -> String -> Acronym
Acronym String
s String
_meaning String
_src) ((String, String) -> Acronym)
-> NonEmpty (String, String) -> NonEmpty Acronym
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (NonEmpty (String, String) -> NonEmpty Acronym)
-> Maybe (NonEmpty (String, String)) -> Maybe (NonEmpty Acronym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Map String (NonEmpty (String, String))
-> Maybe (NonEmpty (String, String))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
s' Map String (NonEmpty (String, String))
all_Acronym_name_index)

searchIndexMeaning ::
  String
  -> [Acronym]
searchIndexMeaning :: String -> [Acronym]
searchIndexMeaning String
s =
  let s' :: String
s' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAlpha (String -> String) -> (String -> String) -> String -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Char -> Char) -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toUpper (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
s
  in  Maybe (NonEmpty Acronym) -> [Acronym]
forall a. Maybe (NonEmpty a) -> [a]
maybeNE (((\(String
_name, String
_src) -> String -> String -> String -> Acronym
Acronym String
_name String
s String
_src) ((String, String) -> Acronym)
-> NonEmpty (String, String) -> NonEmpty Acronym
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (NonEmpty (String, String) -> NonEmpty Acronym)
-> Maybe (NonEmpty (String, String)) -> Maybe (NonEmpty Acronym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Map String (NonEmpty (String, String))
-> Maybe (NonEmpty (String, String))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
s' Map String (NonEmpty (String, String))
all_Acronym_meaning_index)

searchIndexSource ::
  String
  -> [Acronym]
searchIndexSource :: String -> [Acronym]
searchIndexSource String
s =
  let s' :: String
s' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAlpha (String -> String) -> (String -> String) -> String -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Char -> Char) -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toUpper (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
s
  in  Maybe (NonEmpty Acronym) -> [Acronym]
forall a. Maybe (NonEmpty a) -> [a]
maybeNE (((\(String
_name, String
_meaning) -> String -> String -> String -> Acronym
Acronym String
s String
_name String
_meaning) ((String, String) -> Acronym)
-> NonEmpty (String, String) -> NonEmpty Acronym
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (NonEmpty (String, String) -> NonEmpty Acronym)
-> Maybe (NonEmpty (String, String)) -> Maybe (NonEmpty Acronym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Map String (NonEmpty (String, String))
-> Maybe (NonEmpty (String, String))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
s' Map String (NonEmpty (String, String))
all_Acronym_source_index)
  
searchIndexNameMeaning ::
  String
  -> [Acronym]
searchIndexNameMeaning :: String -> [Acronym]
searchIndexNameMeaning String
s =
  String -> [Acronym]
searchIndexName String
s [Acronym] -> [Acronym] -> [Acronym]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> [Acronym]
searchIndexMeaning String
s

searchIndexNameSource ::
  String
  -> [Acronym]
searchIndexNameSource :: String -> [Acronym]
searchIndexNameSource String
s =
  String -> [Acronym]
searchIndexName String
s [Acronym] -> [Acronym] -> [Acronym]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> [Acronym]
searchIndexSource String
s

searchIndexMeaningSource ::
  String
  -> [Acronym]
searchIndexMeaningSource :: String -> [Acronym]
searchIndexMeaningSource String
s =
  String -> [Acronym]
searchIndexMeaning String
s [Acronym] -> [Acronym] -> [Acronym]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> [Acronym]
searchIndexSource String
s
  
searchIndexNameMeaningSource ::
  String
  -> [Acronym]
searchIndexNameMeaningSource :: String -> [Acronym]
searchIndexNameMeaningSource String
s =
  String -> [Acronym]
searchIndexName String
s [Acronym] -> [Acronym] -> [Acronym]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> [Acronym]
searchIndexMeaning String
s [Acronym] -> [Acronym] -> [Acronym]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> [Acronym]
searchIndexSource String
s
  
----

searchFuzzyName ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyName :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyName String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> (Acronym -> String)
-> Bool
-> [Fuzzy Acronym String]
forall s t.
TextualMonoid s =>
s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
Fuzzy.filter String
s [Acronym]
allAcronyms String
before String
after (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
name) Bool
cas

searchFuzzyMeaning ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyMeaning :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyMeaning String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> (Acronym -> String)
-> Bool
-> [Fuzzy Acronym String]
forall s t.
TextualMonoid s =>
s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
Fuzzy.filter String
s [Acronym]
allAcronyms String
before String
after (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
meaning) Bool
cas

searchFuzzySource ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzySource :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzySource String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> (Acronym -> String)
-> Bool
-> [Fuzzy Acronym String]
forall s t.
TextualMonoid s =>
s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
Fuzzy.filter String
s [Acronym]
allAcronyms String
before String
after (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
source) Bool
cas

searchFuzzyNameMeaning ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyNameMeaning :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyNameMeaning String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> [Acronym -> String]
-> Bool
-> [Fuzzy Acronym String]
forall t s.
(Ord t, TextualMonoid s) =>
s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s]
filterN String
s [Acronym]
allAcronyms String
before String
after [(Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
name), (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
meaning)] Bool
cas
  
searchFuzzyNameSource ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyNameSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyNameSource String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> [Acronym -> String]
-> Bool
-> [Fuzzy Acronym String]
forall t s.
(Ord t, TextualMonoid s) =>
s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s]
filterN String
s [Acronym]
allAcronyms String
before String
after [(Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
name), (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
source)] Bool
cas

searchFuzzyMeaningSource ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyMeaningSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyMeaningSource String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> [Acronym -> String]
-> Bool
-> [Fuzzy Acronym String]
forall t s.
(Ord t, TextualMonoid s) =>
s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s]
filterN String
s [Acronym]
allAcronyms String
before String
after [(Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
meaning), (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
source)] Bool
cas

searchFuzzyNameMeaningSource ::
  String
  -> String
  -> String
  -> Bool
  -> [Fuzzy Acronym String]
searchFuzzyNameMeaningSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String]
searchFuzzyNameMeaningSource String
s String
before String
after Bool
cas =
  String
-> [Acronym]
-> String
-> String
-> [Acronym -> String]
-> Bool
-> [Fuzzy Acronym String]
forall t s.
(Ord t, TextualMonoid s) =>
s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s]
filterN String
s [Acronym]
allAcronyms String
before String
after [(Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
name), (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
meaning), (Acronym -> Getting String Acronym String -> String
forall s a. s -> Getting a s a -> a
^. Getting String Acronym String
forall c_a8nA. HasAcronym c_a8nA => Lens' c_a8nA String
source)] Bool
cas

-- https://hackage.haskell.org/package/fuzzy-0.1.0.0/docs/Text-Fuzzy.html#v:filter
filterN ::
  (Ord t, TextualMonoid s) =>
  s
  -> [t]
  -> s
  -> s
  -> [t -> s]
  -> Bool
  -> [Fuzzy t s]
filterN :: s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s]
filterN s
_ [t]
_ s
_ s
_ [] Bool
_ =
  []
filterN s
pattern [t]
values s
before s
after (t -> s
e:[t -> s]
es) Bool
cas =
  let x1 :: [Fuzzy t s]
x1 = s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
forall s t.
TextualMonoid s =>
s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
Fuzzy.filter s
pattern [t]
values s
before s
after t -> s
e Bool
cas
      x1' :: Map t (s, Int)
x1' = [(t, (s, Int))] -> Map t (s, Int)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((\(Fuzzy t
o s
r Int
s) -> (t
o, (s
r, Int
s))) (Fuzzy t s -> (t, (s, Int))) -> [Fuzzy t s] -> [(t, (s, Int))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Fuzzy t s]
x1)
      x2' :: Map t (s, Int)
x2' = (Map t (s, Int) -> (t -> s) -> Map t (s, Int))
-> Map t (s, Int) -> [t -> s] -> Map t (s, Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Map t (s, Int)
m t -> s
e' ->  let x2 :: [Fuzzy t s]
x2 = s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
forall s t.
TextualMonoid s =>
s -> [t] -> s -> s -> (t -> s) -> Bool -> [Fuzzy t s]
Fuzzy.filter s
pattern [t]
values s
before s
after t -> s
e' Bool
cas
                              in (Map t (s, Int) -> Fuzzy t s -> Map t (s, Int))
-> Map t (s, Int) -> [Fuzzy t s] -> Map t (s, Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Map t (s, Int)
m' (Fuzzy t
o s
r Int
s) -> ((s, Int) -> (s, Int) -> (s, Int))
-> t -> (s, Int) -> Map t (s, Int) -> Map t (s, Int)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith (\(s
s1, Int
i1) (s
s2, Int
i2) ->
                                    if Int
i2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
i1 then (s
s2, Int
i2) else (s
s1, Int
i1)) t
o (s
r, Int
s) Map t (s, Int)
m') Map t (s, Int)
m [Fuzzy t s]
x2) Map t (s, Int)
x1' [t -> s]
es
  in  (Fuzzy t s -> Fuzzy t s -> Ordering) -> [Fuzzy t s] -> [Fuzzy t s]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\Fuzzy t s
f1 Fuzzy t s
f2 -> Fuzzy t s -> Int
forall t s. TextualMonoid s => Fuzzy t s -> Int
Fuzzy.score Fuzzy t s
f2 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Fuzzy t s -> Int
forall t s. TextualMonoid s => Fuzzy t s -> Int
Fuzzy.score Fuzzy t s
f1) ((\(t
o, (s
r, Int
s)) -> t -> s -> Int -> Fuzzy t s
forall t s. t -> s -> Int -> Fuzzy t s
Fuzzy t
o s
r Int
s) ((t, (s, Int)) -> Fuzzy t s) -> [(t, (s, Int))] -> [Fuzzy t s]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map t (s, Int) -> [(t, (s, Int))]
forall k a. Map k a -> [(k, a)]
Map.toList Map t (s, Int)
x2')

----

maybeNE ::
  Maybe (NonEmpty a)
  -> [a]
maybeNE :: Maybe (NonEmpty a) -> [a]
maybeNE Maybe (NonEmpty a)
Nothing =
  []
maybeNE (Just (a
h :| [a]
t)) =
  a
ha -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
t