{-# LANGUAGE ViewPatterns #-}

module Distribution.Nixpkgs.Haskell.FromCabal.License
    ( fromCabalLicense
    , fromSPDXLicense
    , isFreeLicense
    ) where

import Data.List (intercalate)
import Distribution.License ( License(..), knownLicenses )
import Distribution.Nixpkgs.License
import Distribution.Pretty (prettyShow)
import qualified Distribution.SPDX as SPDX
import Distribution.Text (display)
import Distribution.Version

-- TODO: Programmatically strip trailing zeros from license version numbers.

fromCabalLicense :: Distribution.License.License -> Distribution.Nixpkgs.License.License
fromCabalLicense :: License -> License
fromCabalLicense (GPL Maybe Version
Nothing)                             = Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just String
"GPL")
fromCabalLicense (GPL (Just (Version -> [Int]
versionNumbers -> [Int
2])))      = String -> License
Known String
"lib.licenses.gpl2"
fromCabalLicense (GPL (Just (Version -> [Int]
versionNumbers -> [Int
3])))      = String -> License
Known String
"lib.licenses.gpl3"
fromCabalLicense (GPL (Just (Version -> [Int]
versionNumbers -> [Int
3,Int
0])))    = String -> License
Known String
"lib.licenses.gpl3"
fromCabalLicense (LGPL Maybe Version
Nothing)                            = Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just String
"LGPL")
fromCabalLicense (LGPL (Just (Version -> [Int]
versionNumbers -> [Int
2,Int
1])))   = String -> License
Known String
"lib.licenses.lgpl21"
fromCabalLicense (LGPL (Just (Version -> [Int]
versionNumbers -> [Int
2])))     = String -> License
Known String
"lib.licenses.lgpl2"
fromCabalLicense (LGPL (Just (Version -> [Int]
versionNumbers -> [Int
3])))     = String -> License
Known String
"lib.licenses.lgpl3"
fromCabalLicense (LGPL (Just (Version -> [Int]
versionNumbers -> [Int
3,Int
0])))   = String -> License
Known String
"lib.licenses.lgpl3"
fromCabalLicense (AGPL Maybe Version
Nothing)                            = Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just String
"AGPL")
fromCabalLicense (AGPL (Just (Version -> [Int]
versionNumbers -> [Int
3])))     = String -> License
Known String
"lib.licenses.agpl3"
fromCabalLicense (AGPL (Just (Version -> [Int]
versionNumbers -> [Int
3,Int
0])))   = String -> License
Known String
"lib.licenses.agpl3"
fromCabalLicense (MPL (Version -> [Int]
versionNumbers ->  [Int
2,Int
0]))          = String -> License
Known String
"lib.licenses.mpl20"
fromCabalLicense License
BSD2                                      = String -> License
Known String
"lib.licenses.bsd2"
fromCabalLicense License
BSD3                                      = String -> License
Known String
"lib.licenses.bsd3"
fromCabalLicense License
BSD4                                      = String -> License
Known String
"lib.licenses.bsdOriginal"
fromCabalLicense License
MIT                                       = String -> License
Known String
"lib.licenses.mit"
fromCabalLicense License
PublicDomain                              = String -> License
Known String
"lib.licenses.publicDomain"
fromCabalLicense License
UnspecifiedLicense                        = String -> License
Known String
"lib.licenses.unfree"
fromCabalLicense License
AllRightsReserved                         = String -> License
Known String
"lib.licenses.unfree"
fromCabalLicense (Apache Maybe Version
Nothing)                          = String -> License
Known String
"lib.licenses.asl20"
fromCabalLicense (Apache (Just (Version -> [Int]
versionNumbers -> [Int
2,Int
0]))) = String -> License
Known String
"lib.licenses.asl20"
fromCabalLicense License
ISC                                       = String -> License
Known String
"lib.licenses.isc"
fromCabalLicense License
OtherLicense                              = Maybe String -> License
Unknown Maybe String
forall a. Maybe a
Nothing
fromCabalLicense (UnknownLicense String
"CC0-1.0")                = String -> License
Known String
"lib.licenses.cc0"
fromCabalLicense (UnknownLicense String
"BSD3ClauseORApache20")   = String -> License
Known String
"lib.licenses.bsd3"
fromCabalLicense License
l                                         = String -> License
forall a. HasCallStack => String -> a
error (String -> License) -> String -> License
forall a b. (a -> b) -> a -> b
$ String
"Distribution.Nixpkgs.Haskell.FromCabal.License.fromCabalLicense: unknown license"
                                                                  String -> String -> String
forall a. [a] -> [a] -> [a]
++ License -> String
forall a. Show a => a -> String
show License
l String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\nChoose one of: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((License -> String) -> [License] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map License -> String
forall a. Pretty a => a -> String
display [License]
knownLicenses)

fromSPDXLicense :: SPDX.License -> Distribution.Nixpkgs.License.License
fromSPDXLicense :: License -> License
fromSPDXLicense License
SPDX.NONE = Maybe String -> License
Unknown Maybe String
forall a. Maybe a
Nothing
fromSPDXLicense (SPDX.License LicenseExpression
expr) =
  case LicenseExpression
expr of
    SPDX.ELicense SimpleLicenseExpression
simpl Maybe LicenseExceptionId
Nothing ->
      -- Not handled: license exceptions
      case SimpleLicenseExpression
simpl of
        SPDX.ELicenseId LicenseId
lid ->
          case LicenseId
lid of
            LicenseId
SPDX.AFL_2_1 -> String -> License
Known String
"lib.licenses.afl21"
            LicenseId
SPDX.AFL_3_0 -> String -> License
Known String
"lib.licenses.afl3"
            LicenseId
SPDX.AGPL_3_0_only -> String -> License
Known String
"lib.licenses.agpl3"
            LicenseId
SPDX.AGPL_3_0_or_later -> String -> License
Known String
"lib.licenses.agpl3Plus"
            LicenseId
SPDX.APSL_2_0 -> String -> License
Known String
"lib.licenses.apsl20"
            LicenseId
SPDX.Artistic_1_0 -> String -> License
Known String
"lib.licenses.artistic1"
            LicenseId
SPDX.Artistic_2_0 -> String -> License
Known String
"lib.licenses.artistic2"
            LicenseId
SPDX.Apache_2_0 -> String -> License
Known String
"lib.licenses.asl20"
            LicenseId
SPDX.BSL_1_0 -> String -> License
Known String
"lib.licenses.boost"
            LicenseId
SPDX.Beerware -> String -> License
Known String
"lib.licenses.beerware"
            LicenseId
SPDX.NullBSD -> String -> License
Known String
"lib.licenses.bsd0"
            LicenseId
SPDX.BSD_2_Clause -> String -> License
Known String
"lib.licenses.bsd2"
            LicenseId
SPDX.BSD_3_Clause -> String -> License
Known String
"lib.licenses.bsd3"
            LicenseId
SPDX.BSD_4_Clause -> String -> License
Known String
"lib.licenses.bsdOriginal"
            LicenseId
SPDX.ClArtistic -> String -> License
Known String
"lib.licenses.clArtistic"
            LicenseId
SPDX.CC0_1_0 -> String -> License
Known String
"lib.licenses.cc0"
            LicenseId
SPDX.CC_BY_NC_SA_2_0 -> String -> License
Known String
"lib.licenses.cc-by-nc-sa-20"
            LicenseId
SPDX.CC_BY_NC_SA_2_5 -> String -> License
Known String
"lib.licenses.cc-by-nc-sa-25"
            LicenseId
SPDX.CC_BY_NC_SA_3_0 -> String -> License
Known String
"lib.licenses.cc-by-nc-sa-30"
            LicenseId
SPDX.CC_BY_NC_SA_4_0 -> String -> License
Known String
"lib.licenses.cc-by-nc-sa-40"
            LicenseId
SPDX.CC_BY_NC_4_0 -> String -> License
Known String
"lib.licenses.cc-by-nc-40"
            LicenseId
SPDX.CC_BY_ND_3_0 -> String -> License
Known String
"lib.licenses.cc-by-nd-30"
            LicenseId
SPDX.CC_BY_SA_2_5 -> String -> License
Known String
"lib.licenses.cc-by-sa-25"
            LicenseId
SPDX.CC_BY_3_0 -> String -> License
Known String
"lib.licenses.cc-by-30"
            LicenseId
SPDX.CC_BY_SA_3_0 -> String -> License
Known String
"lib.licenses.cc-by-sa-30"
            LicenseId
SPDX.CC_BY_4_0 -> String -> License
Known String
"lib.licenses.cc-by-40"
            LicenseId
SPDX.CC_BY_SA_4_0 -> String -> License
Known String
"lib.licenses.cc-by-sa-40"
            LicenseId
SPDX.CDDL_1_0 -> String -> License
Known String
"lib.licenses.cddl"
            LicenseId
SPDX.CECILL_2_0 -> String -> License
Known String
"lib.licenses.cecill20"
            LicenseId
SPDX.CECILL_B -> String -> License
Known String
"lib.licenses.cecill-b"
            LicenseId
SPDX.CECILL_C -> String -> License
Known String
"lib.licenses.cecill-c"
            LicenseId
SPDX.CPAL_1_0 -> String -> License
Known String
"lib.licenses.cpal10"
            LicenseId
SPDX.CPL_1_0 -> String -> License
Known String
"lib.licenses.cpl10"
            LicenseId
SPDX.Curl -> String -> License
Known String
"lib.licenses.curl"
            LicenseId
SPDX.DOC -> String -> License
Known String
"lib.licenses.doc"
            LicenseId
SPDX.EFL_1_0 -> String -> License
Known String
"lib.licenses.efl10"
            LicenseId
SPDX.EFL_2_0 -> String -> License
Known String
"lib.licenses.efl20"
            LicenseId
SPDX.EPL_1_0 -> String -> License
Known String
"lib.licenses.epl10"
            LicenseId
SPDX.EPL_2_0 -> String -> License
Known String
"lib.licenses.epl20"
            LicenseId
SPDX.EUPL_1_1 -> String -> License
Known String
"lib.licenses.eupl11"
            LicenseId
SPDX.GFDL_1_2_only -> String -> License
Known String
"lib.licenses.fdl12"
            LicenseId
SPDX.GFDL_1_3_only -> String -> License
Known String
"lib.licenses.fdl13"
            LicenseId
SPDX.GPL_1_0_only -> String -> License
Known String
"lib.licenses.gpl1"
            LicenseId
SPDX.GPL_1_0_or_later -> String -> License
Known String
"lib.licenses.gpl1Plus"
            LicenseId
SPDX.GPL_2_0_only -> String -> License
Known String
"lib.licenses.gpl2"
            LicenseId
SPDX.GPL_2_0_or_later -> String -> License
Known String
"lib.licenses.gpl2Plus"
            LicenseId
SPDX.GPL_3_0_only -> String -> License
Known String
"lib.licenses.gpl3"
            LicenseId
SPDX.GPL_3_0_or_later -> String -> License
Known String
"lib.licenses.gpl3Plus"
            LicenseId
SPDX.HPND -> String -> License
Known String
"lib.licenses.hpnd"
            LicenseId
SPDX.IJG -> String -> License
Known String
"lib.licenses.ijg"
            LicenseId
SPDX.ImageMagick -> String -> License
Known String
"lib.licenses.imagemagick"
            LicenseId
SPDX.IPA -> String -> License
Known String
"lib.licenses.ipa"
            LicenseId
SPDX.IPL_1_0 -> String -> License
Known String
"lib.licenses.ipl10"
            LicenseId
SPDX.ISC -> String -> License
Known String
"lib.licenses.isc"
            LicenseId
SPDX.LGPL_2_0_only -> String -> License
Known String
"lib.licenses.lgpl2"
            LicenseId
SPDX.LGPL_2_0_or_later -> String -> License
Known String
"lib.licenses.lgpl2Plus"
            LicenseId
SPDX.LGPL_2_1_only -> String -> License
Known String
"lib.licenses.lgpl21"
            LicenseId
SPDX.LGPL_2_1_or_later -> String -> License
Known String
"lib.licenses.lgpl21Plus"
            LicenseId
SPDX.LGPL_3_0_only -> String -> License
Known String
"lib.licenses.lgpl3"
            LicenseId
SPDX.LGPL_3_0_or_later -> String -> License
Known String
"lib.licenses.lgpl3Plus"
            LicenseId
SPDX.Libpng -> String -> License
Known String
"lib.licenses.libpng"
            LicenseId
SPDX.Libtiff -> String -> License
Known String
"lib.licenses.libtiff"
            LicenseId
SPDX.LPPL_1_2 -> String -> License
Known String
"lib.licenses.lppl12"
            LicenseId
SPDX.LPPL_1_3c -> String -> License
Known String
"lib.licenses.lppl13c"
            LicenseId
SPDX.LPL_1_02 -> String -> License
Known String
"lib.licenses.lpl-102"
            LicenseId
SPDX.MIT -> String -> License
Known String
"lib.licenses.mit"
            LicenseId
SPDX.MPL_1_0 -> String -> License
Known String
"lib.licenses.mpl10"
            LicenseId
SPDX.MPL_1_1 -> String -> License
Known String
"lib.licenses.mpl11"
            LicenseId
SPDX.MPL_2_0 -> String -> License
Known String
"lib.licenses.mpl20"
            LicenseId
SPDX.MS_PL -> String -> License
Known String
"lib.licenses.mspl"
            LicenseId
SPDX.NCSA -> String -> License
Known String
"lib.licenses.ncsa"
            LicenseId
SPDX.NPOSL_3_0 -> String -> License
Known String
"lib.licenses.nposl3"
            LicenseId
SPDX.OFL_1_1 -> String -> License
Known String
"lib.licenses.ofl"
            LicenseId
SPDX.OLDAP_2_8 -> String -> License
Known String
"lib.licenses.openldap"
            LicenseId
SPDX.OpenSSL -> String -> License
Known String
"lib.licenses.openssl"
            LicenseId
SPDX.OSL_2_1 -> String -> License
Known String
"lib.licenses.osl21"
            LicenseId
SPDX.OSL_3_0 -> String -> License
Known String
"lib.licenses.osl3"
            LicenseId
SPDX.PHP_3_01 -> String -> License
Known String
"lib.licenses.php201"
            LicenseId
SPDX.PostgreSQL -> String -> License
Known String
"lib.licenses.postgresql"
            LicenseId
SPDX.Python_2_0 -> String -> License
Known String
"lib.licenses.psfl"
            LicenseId
SPDX.QPL_1_0 -> String -> License
Known String
"lib.licenses.qpl"
            LicenseId
SPDX.Ruby -> String -> License
Known String
"lib.licenses.ruby"
            LicenseId
SPDX.Sendmail -> String -> License
Known String
"lib.licenses.sendmail"
            LicenseId
SPDX.SGI_B_2_0 -> String -> License
Known String
"lib.licenses.sgi-b-0"
            LicenseId
SPDX.Sleepycat -> String -> License
Known String
"lib.licenses.sleepycat"
            LicenseId
SPDX.TCL -> String -> License
Known String
"lib.licenses.tcltx"
            LicenseId
SPDX.Unlicense -> String -> License
Known String
"lib.licenses.unlicense"
            LicenseId
SPDX.Vim -> String -> License
Known String
"lib.licenses.vim"
            LicenseId
SPDX.VSL_1_0 -> String -> License
Known String
"lib.licenses.vsl10"
            LicenseId
SPDX.Watcom_1_0 -> String -> License
Known String
"lib.licenses.watcom"
            LicenseId
SPDX.W3C -> String -> License
Known String
"lib.licenses.w3c"
            LicenseId
SPDX.WTFPL -> String -> License
Known String
"lib.licenses.wtfpl"
            LicenseId
SPDX.Zlib -> String -> License
Known String
"lib.licenses.zlib"
            LicenseId
SPDX.ZPL_2_0 -> String -> License
Known String
"lib.licenses.zpl20"
            LicenseId
SPDX.ZPL_2_1 -> String -> License
Known String
"lib.licenses.zpl21"
            LicenseId
_ ->
              -- Licence is not in Nixpkgs.
              -- Use the SPDX expression as a free-form license string.
              Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ LicenseExpression -> String
forall a. Pretty a => a -> String
prettyShow LicenseExpression
expr)
        SimpleLicenseExpression
_ ->
          -- Not handed: the '+' suffix and user-defined licences references.
          -- Use the SPDX expression as a free-form license string.
          Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ LicenseExpression -> String
forall a. Pretty a => a -> String
prettyShow LicenseExpression
expr)
    LicenseExpression
_ ->
      -- Not handled: compound expressions, not expressible in Nixpkgs.
      -- Use the SPDX expression as a free-form license string.
      Maybe String -> License
Unknown (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ LicenseExpression -> String
forall a. Pretty a => a -> String
prettyShow LicenseExpression
expr)

isFreeLicense :: Distribution.Nixpkgs.License.License -> Bool
isFreeLicense :: License -> Bool
isFreeLicense (Known String
"lib.licenses.unfree") = Bool
False
isFreeLicense (Unknown Maybe String
Nothing)             = Bool
False
isFreeLicense License
_                             = Bool
True