find :: BuildMaps -> FilePath -> Maybe (TargetKind, TargetDesc)
find (BuildMaps buildMap childrenMap) path =
  -- Allow specific/simple matches to override pattern matches
  ((,) TargetSimple <$> simpleMatch) `mplus`
  ((,) TargetPattern <$> patternMatch)
  where
    simpleMatch = path `M.lookup` buildMap
    patterns = dbmPatterns $ M.findWithDefault mempty (takeDirectory path) childrenMap
    instantiate pattern = (,) pattern <$> Makefile.instantiatePatternByOutput path pattern
    patternMatch =
      case mapMaybe instantiate patterns of
      [] -> Nothing
      [(_, target)] -> Just $ descOfTarget target
      targets ->
        error $ BS8.unpack $ mconcat
        [ "Multiple matching patterns for: ", BS8.pack (show path), "\n"
        , BS8.unlines $
          map (showPattern . fst) targets
        ]
    showPattern pattern =
      Print.posText (targetPos pattern) <> showPatternOutputs pattern
    showPatternOutputs pattern =
      BS8.unwords $
      map (StringPattern.toString . Makefile.filePatternFile) $
      targetOutputs pattern
find :: BuildMaps -> FilePath -> Maybe (TargetKind, TargetDesc)
find (BuildMaps buildMap childrenMap) path =
  -- Allow specific/simple matches to override pattern matches
  ((,) TargetSimple <$> simpleMatch) `mplus`
  ((,) TargetPattern <$> patternMatch)
  where
    simpleMatch = path `M.lookup` buildMap
    patterns = dbmPatterns $ M.findWithDefault mempty (takeDirectory path) childrenMap
    instantiate pattern = (,) pattern <$> Makefile.instantiatePatternByOutput path pattern
    patternMatch =
      case mapMaybe instantiate patterns of
      [] -> Nothing
      [(_, target)] -> Just $ descOfTarget target
      targets ->
        error $ BS8.unpack $ mconcat
        [ "Multiple matching patterns for: ", BS8.pack (show path), "\n"
        , BS8.unlines $
          map (showPattern . fst) targets
        ]
    showPattern pattern =
      Print.posText (targetPos pattern) <> showPatternOutputs pattern
    showPatternOutputs pattern =
      BS8.unwords $
      map (StringPattern.toString . Makefile.filePatternFile) $
      targetOutputs pattern
find (BuildMaps buildMap childrenMap) path =
  -- Allow specific/simple matches to override pattern matches
  ((,) TargetSimple <$> simpleMatch) `mplus`
  ((,) TargetPattern <$> patternMatch)
  where
    simpleMatch = path `M.lookup` buildMap
    patterns = dbmPatterns $ M.findWithDefault mempty (takeDirectory path) childrenMap
    instantiate pattern = (,) pattern <$> Makefile.instantiatePatternByOutput path pattern
    patternMatch =
      case mapMaybe instantiate patterns of
      [] -> Nothing
      [(_, target)] -> Just $ descOfTarget target
      targets ->
        error $ BS8.unpack $ mconcat
        [ "Multiple matching patterns for: ", BS8.pack (show path), "\n"
        , BS8.unlines $
          map (showPattern . fst) targets
        ]
    showPattern pattern =
      Print.posText (targetPos pattern) <> showPatternOutputs pattern
    showPatternOutputs pattern =
      BS8.unwords $
      map (StringPattern.toString . Makefile.filePatternFile) $
      targetOutputs pattern