module Unison.Codebase.Editor.RemoteRepo where

import Unison.Codebase.Path (Path)
import Unison.Codebase.Path qualified as Path
import Unison.NameSegment qualified as NameSegment
import Unison.Prelude
import Unison.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName)
import Unison.Share.Types

data ShareCodeserver
  = DefaultCodeserver
  | CustomCodeserver CodeserverURI
  deriving stock (ShareCodeserver -> ShareCodeserver -> Bool
(ShareCodeserver -> ShareCodeserver -> Bool)
-> (ShareCodeserver -> ShareCodeserver -> Bool)
-> Eq ShareCodeserver
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ShareCodeserver -> ShareCodeserver -> Bool
== :: ShareCodeserver -> ShareCodeserver -> Bool
$c/= :: ShareCodeserver -> ShareCodeserver -> Bool
/= :: ShareCodeserver -> ShareCodeserver -> Bool
Eq, Eq ShareCodeserver
Eq ShareCodeserver =>
(ShareCodeserver -> ShareCodeserver -> Ordering)
-> (ShareCodeserver -> ShareCodeserver -> Bool)
-> (ShareCodeserver -> ShareCodeserver -> Bool)
-> (ShareCodeserver -> ShareCodeserver -> Bool)
-> (ShareCodeserver -> ShareCodeserver -> Bool)
-> (ShareCodeserver -> ShareCodeserver -> ShareCodeserver)
-> (ShareCodeserver -> ShareCodeserver -> ShareCodeserver)
-> Ord ShareCodeserver
ShareCodeserver -> ShareCodeserver -> Bool
ShareCodeserver -> ShareCodeserver -> Ordering
ShareCodeserver -> ShareCodeserver -> ShareCodeserver
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ShareCodeserver -> ShareCodeserver -> Ordering
compare :: ShareCodeserver -> ShareCodeserver -> Ordering
$c< :: ShareCodeserver -> ShareCodeserver -> Bool
< :: ShareCodeserver -> ShareCodeserver -> Bool
$c<= :: ShareCodeserver -> ShareCodeserver -> Bool
<= :: ShareCodeserver -> ShareCodeserver -> Bool
$c> :: ShareCodeserver -> ShareCodeserver -> Bool
> :: ShareCodeserver -> ShareCodeserver -> Bool
$c>= :: ShareCodeserver -> ShareCodeserver -> Bool
>= :: ShareCodeserver -> ShareCodeserver -> Bool
$cmax :: ShareCodeserver -> ShareCodeserver -> ShareCodeserver
max :: ShareCodeserver -> ShareCodeserver -> ShareCodeserver
$cmin :: ShareCodeserver -> ShareCodeserver -> ShareCodeserver
min :: ShareCodeserver -> ShareCodeserver -> ShareCodeserver
Ord, Int -> ShareCodeserver -> ShowS
[ShareCodeserver] -> ShowS
ShareCodeserver -> String
(Int -> ShareCodeserver -> ShowS)
-> (ShareCodeserver -> String)
-> ([ShareCodeserver] -> ShowS)
-> Show ShareCodeserver
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ShareCodeserver -> ShowS
showsPrec :: Int -> ShareCodeserver -> ShowS
$cshow :: ShareCodeserver -> String
show :: ShareCodeserver -> String
$cshowList :: [ShareCodeserver] -> ShowS
showList :: [ShareCodeserver] -> ShowS
Show)

newtype ShareUserHandle = ShareUserHandle {ShareUserHandle -> Text
shareUserHandleToText :: Text}
  deriving stock (ShareUserHandle -> ShareUserHandle -> Bool
(ShareUserHandle -> ShareUserHandle -> Bool)
-> (ShareUserHandle -> ShareUserHandle -> Bool)
-> Eq ShareUserHandle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ShareUserHandle -> ShareUserHandle -> Bool
== :: ShareUserHandle -> ShareUserHandle -> Bool
$c/= :: ShareUserHandle -> ShareUserHandle -> Bool
/= :: ShareUserHandle -> ShareUserHandle -> Bool
Eq, Eq ShareUserHandle
Eq ShareUserHandle =>
(ShareUserHandle -> ShareUserHandle -> Ordering)
-> (ShareUserHandle -> ShareUserHandle -> Bool)
-> (ShareUserHandle -> ShareUserHandle -> Bool)
-> (ShareUserHandle -> ShareUserHandle -> Bool)
-> (ShareUserHandle -> ShareUserHandle -> Bool)
-> (ShareUserHandle -> ShareUserHandle -> ShareUserHandle)
-> (ShareUserHandle -> ShareUserHandle -> ShareUserHandle)
-> Ord ShareUserHandle
ShareUserHandle -> ShareUserHandle -> Bool
ShareUserHandle -> ShareUserHandle -> Ordering
ShareUserHandle -> ShareUserHandle -> ShareUserHandle
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ShareUserHandle -> ShareUserHandle -> Ordering
compare :: ShareUserHandle -> ShareUserHandle -> Ordering
$c< :: ShareUserHandle -> ShareUserHandle -> Bool
< :: ShareUserHandle -> ShareUserHandle -> Bool
$c<= :: ShareUserHandle -> ShareUserHandle -> Bool
<= :: ShareUserHandle -> ShareUserHandle -> Bool
$c> :: ShareUserHandle -> ShareUserHandle -> Bool
> :: ShareUserHandle -> ShareUserHandle -> Bool
$c>= :: ShareUserHandle -> ShareUserHandle -> Bool
>= :: ShareUserHandle -> ShareUserHandle -> Bool
$cmax :: ShareUserHandle -> ShareUserHandle -> ShareUserHandle
max :: ShareUserHandle -> ShareUserHandle -> ShareUserHandle
$cmin :: ShareUserHandle -> ShareUserHandle -> ShareUserHandle
min :: ShareUserHandle -> ShareUserHandle -> ShareUserHandle
Ord, Int -> ShareUserHandle -> ShowS
[ShareUserHandle] -> ShowS
ShareUserHandle -> String
(Int -> ShareUserHandle -> ShowS)
-> (ShareUserHandle -> String)
-> ([ShareUserHandle] -> ShowS)
-> Show ShareUserHandle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ShareUserHandle -> ShowS
showsPrec :: Int -> ShareUserHandle -> ShowS
$cshow :: ShareUserHandle -> String
show :: ShareUserHandle -> String
$cshowList :: [ShareUserHandle] -> ShowS
showList :: [ShareUserHandle] -> ShowS
Show)

-- |
-- >>> :set -XOverloadedLists
-- >>> import Data.Maybe (fromJust)
-- >>> import Network.URI
-- >>> displayShareCodeserver DefaultCodeserver "share" ["base", "List"]
-- "share.base.List"
-- >>> displayShareCodeserver DefaultCodeserver "share" []
-- "share"
-- >>> displayShareCodeserver (CustomCodeserver . fromJust $ parseURI "https://share-next.unison-lang.org/api" >>= codeserverFromURI ) "unison" ["base", "List"]
-- "share(https://share-next.unison-lang.org:443/api).unison.base.List"
displayShareCodeserver :: ShareCodeserver -> ShareUserHandle -> Path -> Text
displayShareCodeserver :: ShareCodeserver -> ShareUserHandle -> Path -> Text
displayShareCodeserver ShareCodeserver
cs ShareUserHandle
shareUser Path
path =
  let shareServer :: Text
shareServer = case ShareCodeserver
cs of
        ShareCodeserver
DefaultCodeserver -> Text
""
        CustomCodeserver CodeserverURI
cu -> Text
"share(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CodeserverURI -> Text
forall a. Show a => a -> Text
tShow CodeserverURI
cu Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")."
   in Text
shareServer Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ShareUserHandle -> Text
shareUserHandleToText ShareUserHandle
shareUser Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Path -> Text
maybePrintPath Path
path

-- | print remote namespace
printReadRemoteNamespace :: (a -> Text) -> ReadRemoteNamespace a -> Text
printReadRemoteNamespace :: forall a. (a -> Text) -> ReadRemoteNamespace a -> Text
printReadRemoteNamespace a -> Text
printProject = \case
  ReadShare'LooseCode ReadShareLooseCode {ShareCodeserver
server :: ShareCodeserver
$sel:server:ReadShareLooseCode :: ReadShareLooseCode -> ShareCodeserver
server, ShareUserHandle
repo :: ShareUserHandle
$sel:repo:ReadShareLooseCode :: ReadShareLooseCode -> ShareUserHandle
repo, Path
path :: Path
$sel:path:ReadShareLooseCode :: ReadShareLooseCode -> Path
path} -> ShareCodeserver -> ShareUserHandle -> Path -> Text
displayShareCodeserver ShareCodeserver
server ShareUserHandle
repo Path
path
  ReadShare'ProjectBranch a
project -> a -> Text
printProject a
project

-- | Render a 'WriteRemoteNamespace' as text.
printWriteRemoteNamespace :: (ProjectAndBranch ProjectName ProjectBranchName) -> Text
printWriteRemoteNamespace :: ProjectAndBranch ProjectName ProjectBranchName -> Text
printWriteRemoteNamespace ProjectAndBranch ProjectName ProjectBranchName
projectAndBranch = forall target source. From source target => source -> target
into @Text ProjectAndBranch ProjectName ProjectBranchName
projectAndBranch

maybePrintPath :: Path -> Text
maybePrintPath :: Path -> Text
maybePrintPath Path
path =
  if Path
path Path -> Path -> Bool
forall a. Eq a => a -> a -> Bool
== Path
Path.empty
    then Text
forall a. Monoid a => a
mempty
    else Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Path -> Text
Path.toText Path
path

data ReadRemoteNamespace a
  = ReadShare'LooseCode !ReadShareLooseCode
  | -- | A remote project+branch, specified by name (e.g. @unison/base/main).
    -- Currently assumed to be hosted on Share, though we could include a ShareCodeserver in here, too.
    ReadShare'ProjectBranch !a
  deriving stock (ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
(ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool)
-> (ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool)
-> Eq (ReadRemoteNamespace a)
forall a.
Eq a =>
ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a.
Eq a =>
ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
== :: ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
$c/= :: forall a.
Eq a =>
ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
/= :: ReadRemoteNamespace a -> ReadRemoteNamespace a -> Bool
Eq, (forall a b.
 (a -> b) -> ReadRemoteNamespace a -> ReadRemoteNamespace b)
-> (forall a b.
    a -> ReadRemoteNamespace b -> ReadRemoteNamespace a)
-> Functor ReadRemoteNamespace
forall a b. a -> ReadRemoteNamespace b -> ReadRemoteNamespace a
forall a b.
(a -> b) -> ReadRemoteNamespace a -> ReadRemoteNamespace b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b.
(a -> b) -> ReadRemoteNamespace a -> ReadRemoteNamespace b
fmap :: forall a b.
(a -> b) -> ReadRemoteNamespace a -> ReadRemoteNamespace b
$c<$ :: forall a b. a -> ReadRemoteNamespace b -> ReadRemoteNamespace a
<$ :: forall a b. a -> ReadRemoteNamespace b -> ReadRemoteNamespace a
Functor, Int -> ReadRemoteNamespace a -> ShowS
[ReadRemoteNamespace a] -> ShowS
ReadRemoteNamespace a -> String
(Int -> ReadRemoteNamespace a -> ShowS)
-> (ReadRemoteNamespace a -> String)
-> ([ReadRemoteNamespace a] -> ShowS)
-> Show (ReadRemoteNamespace a)
forall a. Show a => Int -> ReadRemoteNamespace a -> ShowS
forall a. Show a => [ReadRemoteNamespace a] -> ShowS
forall a. Show a => ReadRemoteNamespace a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> ReadRemoteNamespace a -> ShowS
showsPrec :: Int -> ReadRemoteNamespace a -> ShowS
$cshow :: forall a. Show a => ReadRemoteNamespace a -> String
show :: ReadRemoteNamespace a -> String
$cshowList :: forall a. Show a => [ReadRemoteNamespace a] -> ShowS
showList :: [ReadRemoteNamespace a] -> ShowS
Show, (forall x. ReadRemoteNamespace a -> Rep (ReadRemoteNamespace a) x)
-> (forall x.
    Rep (ReadRemoteNamespace a) x -> ReadRemoteNamespace a)
-> Generic (ReadRemoteNamespace a)
forall x. Rep (ReadRemoteNamespace a) x -> ReadRemoteNamespace a
forall x. ReadRemoteNamespace a -> Rep (ReadRemoteNamespace a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (ReadRemoteNamespace a) x -> ReadRemoteNamespace a
forall a x. ReadRemoteNamespace a -> Rep (ReadRemoteNamespace a) x
$cfrom :: forall a x. ReadRemoteNamespace a -> Rep (ReadRemoteNamespace a) x
from :: forall x. ReadRemoteNamespace a -> Rep (ReadRemoteNamespace a) x
$cto :: forall a x. Rep (ReadRemoteNamespace a) x -> ReadRemoteNamespace a
to :: forall x. Rep (ReadRemoteNamespace a) x -> ReadRemoteNamespace a
Generic)

data ReadShareLooseCode = ReadShareLooseCode
  { ReadShareLooseCode -> ShareCodeserver
server :: !ShareCodeserver,
    ReadShareLooseCode -> ShareUserHandle
repo :: !ShareUserHandle,
    -- sch :: Maybe ShortCausalHash, -- maybe later
    ReadShareLooseCode -> Path
path :: !Path
  }
  deriving stock (ReadShareLooseCode -> ReadShareLooseCode -> Bool
(ReadShareLooseCode -> ReadShareLooseCode -> Bool)
-> (ReadShareLooseCode -> ReadShareLooseCode -> Bool)
-> Eq ReadShareLooseCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReadShareLooseCode -> ReadShareLooseCode -> Bool
== :: ReadShareLooseCode -> ReadShareLooseCode -> Bool
$c/= :: ReadShareLooseCode -> ReadShareLooseCode -> Bool
/= :: ReadShareLooseCode -> ReadShareLooseCode -> Bool
Eq, Int -> ReadShareLooseCode -> ShowS
[ReadShareLooseCode] -> ShowS
ReadShareLooseCode -> String
(Int -> ReadShareLooseCode -> ShowS)
-> (ReadShareLooseCode -> String)
-> ([ReadShareLooseCode] -> ShowS)
-> Show ReadShareLooseCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReadShareLooseCode -> ShowS
showsPrec :: Int -> ReadShareLooseCode -> ShowS
$cshow :: ReadShareLooseCode -> String
show :: ReadShareLooseCode -> String
$cshowList :: [ReadShareLooseCode] -> ShowS
showList :: [ReadShareLooseCode] -> ShowS
Show)

isPublic :: ReadShareLooseCode -> Bool
isPublic :: ReadShareLooseCode -> Bool
isPublic ReadShareLooseCode {Path
$sel:path:ReadShareLooseCode :: ReadShareLooseCode -> Path
path :: Path
path} =
  case Path
path of
    (NameSegment
segment Path.:< Path
_) -> NameSegment
segment NameSegment -> NameSegment -> Bool
forall a. Eq a => a -> a -> Bool
== NameSegment
NameSegment.publicLooseCodeSegment
    Path
_ -> Bool
False