<commit_before>module Components.Auth exposing
  ( Model, Message
  , init, token, update, subscriptions, view, css
  , decodeCode
  )

import Html exposing (Html, node, a, text, div)
import Html.Events exposing (on)
import Html.Attributes exposing (attribute, href, target, id)
import Html.CssHelpers exposing (withNamespace)
import Css.Namespace exposing (namespace)
import Css exposing
  ( Stylesheet
  , stylesheet, (.)
  , property
  )
import Json.Decode as Decode exposing (Decoder, andThen)
import Http
import Task

import Components.IconButton as IconButton

{class} =
  withNamespace componentNamespace


-- MODEL

type alias Model =
  { token : Maybe String
  , code : Maybe String
  , failureMessages : List String
  }

init : (Model, Cmd Message)
init =
  { token = Nothing
  , code = Nothing
  , failureMessages = []
  }
  ! []

token : Model -> Maybe String
token = .token


-- UPDATE

type Message
  = ReceiveToken String
  | FailReceivingToken Http.Error
  | ReceiveCode Code
  | Noop ()

type alias Code =
  Maybe String

update : Message -> Model -> (Model, Cmd Message)
update message model =
  case message of
    ReceiveToken token ->
      { model
      | token = Just token
      }
      ! []

    FailReceivingToken _ ->
      { model
      | code = Nothing
      , failureMessages =
        "Blimey! Failed to get a github authentication token."
        :: model.failureMessages
      }
      ! []

    ReceiveCode (Just code) ->
      let
        fetchToken =
          Http.get
            (Decode.at ["token"] Decode.string)
            ("http://parametric-svg-auth.herokuapp.com/authenticate/" ++ code)

      in
        { model
        | code = Just code
        }
        ! [ Task.perform FailReceivingToken ReceiveToken fetchToken
          ]

    ReceiveCode Nothing ->
      { model
      | failureMessages =
        "Yikes! Failed to get an authentication code from github."
        :: model.failureMessages
      }
      ! []

    Noop _ ->
      model ! []


-- SUBSCRIPTIONS
<commit_msg>Cache token in localStorage<commit_after>module Components.Auth exposing
  ( Model, Message
  , init, token, update, subscriptions, view, css
  , decodeCode
  )

import Html exposing (Html, node, a, text, div)
import Html.Events exposing (on)
import Html.Attributes exposing (attribute, href, target, id)
import Html.CssHelpers exposing (withNamespace)
import Css.Namespace exposing (namespace)
import Css exposing
  ( Stylesheet
  , stylesheet, (.)
  , property
  )
import Json.Decode as Decode exposing (Decoder, andThen)
import Http
import Task
import LocalStorage

import Components.IconButton as IconButton

{class} =
  withNamespace componentNamespace


-- MODEL

type alias Model =
  { token : Maybe String
  , code : Maybe String
  , failureMessages : List String
  }

init : (Model, Cmd Message)
init =
  { token = Nothing
  , code = Nothing
  , failureMessages = []
  }
  ! [ LocalStorage.get storageKey
      |> Task.perform FailLoadingToken LoadToken
    ]

token : Model -> Maybe String
token = .token


-- UPDATE

type Message
  = LoadToken (Maybe String)
  | FailLoadingToken LocalStorage.Error
  | ReceiveToken String
  | FailReceivingToken Http.Error
  | FailSavingToken LocalStorage.Error
  | ReceiveCode Code
  | Noop ()

type alias Code =
  Maybe String

update : Message -> Model -> (Model, Cmd Message)
update message model =
  let
    withFailure message model =
      { model
      | failureMessages = message :: model.failureMessages
      }

  in
    case message of
      LoadToken (Just token) ->
        { model
        | token = Just token
        } ! []

      LoadToken Nothing ->
        model ! []

      FailLoadingToken _ ->
        model ! []

      ReceiveToken token ->
        { model
        | token = Just token
        }
        ! [ LocalStorage.set storageKey token
            |> Task.perform FailSavingToken Noop
          ]

      FailSavingToken _ ->
        withFailure
          ( "Damn, we haven’t managed to save authentication details "
          ++ "for the future. Never mind though, you can keep using the app. "
          ++ "All your changes will be saved to gist as always. "
          ++ "You’ll just have to log in next time as well."
          )
          model
        ! []

      FailReceivingToken _ ->
        withFailure "Blimey! Failed to get a github authentication token."
          { model
          | code = Nothing
          }
        ! []

      ReceiveCode (Just code) ->
        let
          fetchToken =
            Http.get
              (Decode.at ["token"] Decode.string)
              ("http://parametric-svg-auth.herokuapp.com/authenticate/" ++ code)

        in
          { model
          | code = Just code
          }
          ! [ Task.perform FailReceivingToken ReceiveToken fetchToken
            ]

      ReceiveCode Nothing ->
        withFailure "Yikes! Failed to get an authentication code from github."
          model
        ! []

      Noop _ ->
        model ! []


storageKey : String
storageKey =
  componentNamespace ++ "auth-key"


-- SUBSCRIPTIONS

{'fraction_non_alphanumeric': 0.08784715383100256, 'fraction_numerical': 0.0, 'mean_word_length': 2.201765447667087, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2981882', 'n_tokens_mistral': 1474, 'n_tokens_neox': 1410, 'n_words': 442}