(ns ajet.chat.auth-gw.auth-integration-test
  (:require [clojure.test :refer [deftest testing is use-fixtures]]
            [ajet.chat.auth-gw.auth :as auth]
            [ajet.chat.shared.db :as db]
            [ajet.chat.test-helpers :as th]))

(use-fixtures :once th/with-db-suite)
(use-fixtures :each th/with-clean-db)

;;; ---------------------------------------------------------------------------
;;; Session create / validate / destroy
;;; ---------------------------------------------------------------------------

(deftest create-session-returns-token
  (let [user  (th/create-user!)
        token (auth/create-session! th/*ds* (:id user) 30)]
    (is (string? token))
    (is (pos? (count token)))))

(deftest validate-session-with-valid-token
  (let [user  (th/create-user!)
        token (auth/create-session! th/*ds* (:id user) 30)
        result (auth/validate-session th/*ds* token)]
    (is (some? result))
    (is (= (str (:id user)) (:user-id result)))
    (is (some? (:session-id result)))))

(deftest validate-session-with-invalid-token
  (is (nil? (auth/validate-session th/*ds* "invalid-token-value"))))

(deftest validate-session-with-nil-token
  (is (nil? (auth/validate-session th/*ds* nil))))

(deftest validate-session-with-empty-token
  (is (nil? (auth/validate-session th/*ds* ""))))

(deftest destroy-session-clears-cookie
  (let [user    (th/create-user!)
        token   (auth/create-session! th/*ds* (:id user) 30)
        result  (auth/destroy-session! th/*ds* token "ajet_session" false)]
    (is (map? result))
    (is (= "" (get-in result [:cookies "ajet_session" :value])))
    (is (= 0 (get-in result [:cookies "ajet_session" :max-age])))
    ;; Session should now be invalid
    (is (nil? (auth/validate-session th/*ds* token)))))

;;; ---------------------------------------------------------------------------
;;; OAuth user creation
;;; ---------------------------------------------------------------------------

(deftest create-user-from-oauth
  (let [profile {:username          "octocat"
                 :display-name      "Octo Cat"
                 :email             "octocat@example.com"
                 :avatar-url        "https://example.com/avatar.png"
                 :provider          :github
                 :provider-user-id  "12345"
                 :provider-username "octocat"}
        user (auth/create-user-from-oauth! th/*ds* profile)]
    (is (some? user))
    (is (= "octocat" (:username user)))))

(deftest find-user-by-oauth
  (let [profile {:username          "findme"
                 :display-name      "Find Me"
                 :email             "findme@example.com"
                 :provider          :github
                 :provider-user-id  "99999"
                 :provider-username "findme"}
        _ (auth/create-user-from-oauth! th/*ds* profile)
        found (auth/find-user-by-oauth th/*ds* :github "99999")]
    (is (some? found))
    (is (= "findme" (:username found)))))

(deftest find-user-by-oauth-not-found
  (is (nil? (auth/find-user-by-oauth th/*ds* :github "nonexistent-id"))))
