<?php

require_once "config.php";
require_once "tools.php";
require_once "usk.php";


function output_person($host,$user)
{
  global $public_key_file;
  
  // Public Key
  // Hent fra fil, .pem
  $key = openssl_get_publickey($public_key_file); // "file://data/pu.pem"  
  if($key === false) http_response_code(500) && die('Failed to read public key.'."\n");
  // eksporter til string
  $keyString = openssl_pkey_get_details($key)["key"];
  $keyString = str_replace("\n", '\n', $keyString);

  $uuser = url_user($host,$user);
    
  echo <<<END
{
   "@context":[
      "https://www.w3.org/ns/activitystreams",
      "https://w3id.org/security/v1",
      {
         "addressRegion":"sc:addressRegion",
         "timezone":{
            "@id":"mz:timezone",
            "@type":"sc:Text"
         },
         "isOnline":{
            "@id":"mz:isOnline",
            "@type":"sc:Boolean"
         },
         "pt":"https://joinpeertube.org/ns#",
         "manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
         "inLanguage":"sc:inLanguage",
         "address":{
            "@id":"sc:address",
            "@type":"sc:PostalAddress"
         },
         "discoverable":"toot:discoverable",
         "repliesModerationOption":{
            "@id":"mz:repliesModerationOption",
            "@type":"mz:repliesModerationOptionType"
         },
         "sc":"http://schema.org#",
         "mz":"https://joinmobilizon.org/ns#",
         "category":"sc:category",
         "joinModeType":{
            "@id":"mz:joinModeType",
            "@type":"rdfs:Class"
         },
         "Hashtag":"as:Hashtag",
         "propertyID":"sc:propertyID",
         "PostalAddress":"sc:PostalAddress",
         "discussions":{
            "@id":"mz:discussions",
            "@type":"@id"
         },
         "remainingAttendeeCapacity":"sc:remainingAttendeeCapacity",
         "streetAddress":"sc:streetAddress",
         "anonymousParticipationEnabled":{
            "@id":"mz:anonymousParticipationEnabled",
            "@type":"sc:Boolean"
         },
         "addressLocality":"sc:addressLocality",
         "joinMode":{
            "@id":"mz:joinMode",
            "@type":"mz:joinModeType"
         },
         "location":{
            "@id":"sc:location",
            "@type":"sc:Place"
         },
         "toot":"http://joinmastodon.org/ns#",
         "participantCount":{
            "@id":"mz:participantCount",
            "@type":"sc:Integer"
         },
         "uuid":"sc:identifier",
         "maximumAttendeeCapacity":"sc:maximumAttendeeCapacity",
         "participationMessage":{
            "@id":"mz:participationMessage",
            "@type":"sc:Text"
         },
         "openness":{
            "@id":"mz:openness",
            "@type":"@id"
         },
         "members":{
            "@id":"mz:members",
            "@type":"@id"
         },
         "events":{
            "@id":"mz:events",
            "@type":"@id"
         },
         "resources":{
            "@id":"mz:resources",
            "@type":"@id"
         },
         "addressCountry":"sc:addressCountry",
         "posts":{
            "@id":"mz:posts",
            "@type":"@id"
         },
         "commentsEnabled":{
            "@id":"pt:commentsEnabled",
            "@type":"sc:Boolean"
         },
         "value":"sc:value",
         "PropertyValue":"sc:PropertyValue",
         "repliesModerationOptionType":{
            "@id":"mz:repliesModerationOptionType",
            "@type":"rdfs:Class"
         },
         "todos":{
            "@id":"mz:todos",
            "@type":"@id"
         },
         "ical":"http://www.w3.org/2002/12/cal/ical#",
         "postalCode":"sc:postalCode",
         "memberCount":{
            "@id":"mz:memberCount",
            "@type":"sc:Integer"
         },
         "@language":"und"
      }
   ],
   "discoverable":false,
   "discussions":null,
   "endpoints":{
      "discussions":null,
      "events":null,
      "members":null,
      "posts":null,
      "resources":null,
      "sharedInbox":null,
      "todos":null
   },
   "events":null,

   "id":"$uuser/",
   "inbox":null,
   "manuallyApprovesFollowers":false,
   "members":null,
   "name":"$user",
   "openness":"moderated",
   "outbox":null,
   "posts":null,
   "preferredUsername":"$user",
  "publicKey": {
        "id": "$uuser/#main-key",
        "owner": "$uuser/",
        "publicKeyPem": "$keyString"
  },
   "resources":null,
   "summary":"Utprøvingskonto",
   "todos":null,
   "type":"Person",
   "url":"$uuser/"
}
END;
}


// TODO:Replace Halden

function output_minimal($host,$user)
{
  global $public_key_file;
  global $preps;
  global $prefixname;
  
  $puser = rawurldecode($user);
  $name = truename($puser);
  $prep = $preps[$user];
  $uuser = url_user($host,$user);
  $timestamp = date( "c" );
          
  // Public Key
  // Hent fra fil, .pem
  $key = openssl_get_publickey($public_key_file); // "file://data/pu.pem"  
  // $key = openssl_get_publickey("file://data/pu.pem"); 
  if($key === false) http_response_code(500) && die('Failed to read public key.'."\n");
  // eksporter til string
  $keyString = openssl_pkey_get_details($key)["key"];
  $keyString = str_replace("\n", '\n', $keyString);
  //if (!openssl_pkey_export($key, $keyString)) http_response_code(500) && die('Failed to retrieve public key.'.$keyString."\n");

  $icon = create_icon($host,"image/$user.png");
  
  echo <<<END
{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1"
  ],
  "id": "$uuser/",
  "discoverable": true,
  "manuallyApprovesFollowers": false,
  "indexable": false,
  "memorial": false,
  "type": "Group",
  "followers": "$uuser/followers",
  "following": "$uuser/following",
  "members": "$uuser/members",
  "outbox": "$uuser/outbox",
  "inbox": "$uuser/inbox",
  "events": "$uuser/events",
  "preferredUsername": "$puser",
  "name": "$prefixname $prep $name",
  "summary": "Hendelser $prep $name. Eksperimentell bro fra Underskog. ",
  "url": "$uuser/",
  "published": "$timestamp",
  "publicKey": {
        "id": "$uuser/#main-key",
        "owner": "$uuser/",
        "publicKeyPem": "$keyString"
  },
  "endpoints": {
    "members": "$uuser/members",
    "events" : "$uuser/events"
  },
  "location":{
      "address":{
         "addressCountry":"Norway",
         "addressLocality":"Østfold",
         "addressRegion":null,
         "postalCode":null,
         "streetAddress":null,
         "type":"PostalAddress"
      },
      "id":"https://usk.akerbaek.no/address/$user",
      "latitude":59.0680555,
      "longitude":11.537191002239753,
      "name":"$name",
      "type":"Place"
   },  
  "icon": $icon
}
END;

//,
//  "endpoints": {
//        "sharedInbox": "https://$host/inbox"
//    }

}

// TODO: Lag title og description som kan brukes av mastodon embed.  
function output_profile_html($host,$user,$redir,$no='')
{
  global $preps;
  global $prefixname;
  
  $puser = rawurldecode($user);
  $name = truename($puser);
  $prep = $preps[$user];
  $title = "$prefixname $prep $name";

  $uuser = url_user($host,$user);
  
  echo <<<END
<html>
<head>
  <title>$title</title>
  <link href="$uuser/embed/$no" rel='alternate' type='application/json+oembed'>
  <meta http-equiv="refresh" content="0; url=$redir">
  <meta name="description" content="Underskogsevenement">
  <meta itemprop="title" content="$title">
  <meta itemprop="description" content="Undertittel">
</head>
<body>
  <h1>$title</h1>
  <p>Hendelser $prep $name. Eksperimentell bro fra Underskog.</p>
</body>
</html>
END;
}

function output_page_html($host,$user,$event,$no='')
{
  global $preps;
  global $prefixname;
  
  $puser = rawurldecode($user);
  $name  = truename($puser);
  $prep  = $preps[$user];
  $title = "$prefixname $prep $name";
  $uuser = url_user($host,$user);
  $content = json_decode(create_text_content($event,$user));
  $desc  = strip_tags(create_description($event));
  $s     = $event->summary;
  $redir = get_main_url($event);
  
  echo <<<END
<html>
<head>
  <title>$title</title>
  <link href="$uuser/embed/$no" rel='alternate' type='application/json+oembed'>
  <meta http-equiv="refresh" content="0; url=$redir">
  <meta name="description" content="$desc">
  <meta name="og:title" content="$s">
</head>
<body>
  <h1>$title</h1>
  <p>Hendelser $prep $name. Eksperimentell bro fra Underskog.</p>
  $content
</body>
</html>
END;
}

// Fediverse software group (Mastodon/Mobilizon etc)
function get_fedi_family($sign)
{
  if(!isset($sign)) return "unknown";
  if(strpos($sign,"keyId") === false) return "unknown";
  preg_match("/keyId=\"(.*)\/([A-Za-z]*)[\",#].*/", $sign, $m);
 
  $p = $m[1].'/'.$m[2];

  log_text("Extracted follower from signature",$p);
  global $sqluser, $sqlpass, $sqldb;
   
  $mysqli = mysqli_connect('localhost', $sqluser, $sqlpass, $sqldb);
  
  // create a prepared statement 
  $stmt = mysqli_prepare($mysqli, "SELECT family FROM `usk_subs` WHERE `follower` LIKE ?;");

  // bind parameters for markers 
  mysqli_stmt_bind_param($stmt, "s", $p); 

  // execute query 
  mysqli_stmt_execute($stmt);
  
  mysqli_stmt_bind_result($stmt, $ret);
  mysqli_stmt_fetch($stmt);
  
  mysqli_stmt_close($stmt);
  mysqli_close($mysqli);   

  return $ret;
}
 
function get_lastone($user)
{
 global $sqluser, $sqlpass, $sqldb;
   
 $mysqli = mysqli_connect('localhost', $sqluser, $sqlpass, $sqldb);
  
 // create a prepared statement 
 $stmt = mysqli_prepare($mysqli, "SELECT lastone FROM `usk_subs` WHERE `town` = ?;");

 // bind parameters for markers 
 mysqli_stmt_bind_param($stmt, "s", $user); 

 // execute query 
 mysqli_stmt_execute($stmt);
 
 mysqli_stmt_bind_result($stmt, $ret);
 mysqli_stmt_fetch($stmt);
  
 mysqli_stmt_close($stmt);
 mysqli_close($mysqli);   
 
 return($ret);
}



function output_outbox($host,$user)
{
  $last = get_lastone($user);
  $ical = get_ics($user,false);
  $mains   = get_used_main_events($ical,$last);
  $c = count($mains);
  log_text("Recent events",$c);
  if($c == 0)
      return;
  $uuser = url_user($host,$user);
  $ti = $c*2 + 1;
  $context = create_event_context();
  echo <<<END
{
  $context,
  "id": "$uuser/outbox",
  "type": "OrderedCollection",
  "totalItems": $ti,
  "orderedItems": [
END;
  // TODO: Flytt context fra hvert event og legg foran orderedItems
  while($first = array_pop($mains))
  {
    $id       = get_id($first);
    $content  = create_text_content($first,$user);
    $post_item  = create_post($host,$user,id2usk($id),$content);
    $event_item = create_event($host,$user,$user,id2usk($id),$first);
    echo "$post_item,";
    echo "$event_item,";
  }
  $uid     = id2usk(rand() + 130000);
  $content = json_encode("Ikke fler evenementer");
  $item    = create_post($host,$user,$uid,$content);
  echo <<<END
    $item
  ]
}

END;
}
          

function output_events($host,$user)
{
  $last = get_lastone($user);
  $ical = get_ics($user,false);
  $mains   = get_used_main_events($ical,$last);
  $c = count($mains);
  log_text("Recent events",$c);
  if($c == 0)
      return;
  $uuser = url_user($host,$user);
  $context = create_event_context();
  echo <<<END
{
  $context,
  "id": "$uuser/events",
  "type": "OrderedCollection",
  "totalItems": $c,
  "orderedItems": [
END;

  while($first = array_pop($mains))
  {
    $id       = get_id($first);
    $item = create_event($host,$user,$user,id2usk($id),$first);
    echo "\n$item";
    if(!empty($mains))
      echo(",");
  }

  echo <<<END

  ]
}

END;
}
          
function output_members($host,$user)
{
  $uuser = url_user($host,$user);
  $owner = url_user($host,"enannenen");
  
  echo <<<END
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "$uuser/members",
  "type": "OrderedCollection",
  "totalItems": 1,
  "orderedItems": [
    {
      "type"  : "Member",
      "id"    : "https://$host/member/1",
      "actor" : "$owner/",
      "object": "$uuser/",
      "role"  : "ADMINISTRATOR"
    },
    {
      "type"  : "Member",
      "id"    : "https://$host/member/2",
      "actor" : "https://rheinneckar.events/@enannenen",
      "object": "$uuser/",
      "role"  : "MODERATOR"
    }

  ]
}
END;

}

function count_followers($user)
{
 global $sqluser, $sqlpass, $sqldb;
   
 $mysqli = mysqli_connect('localhost', $sqluser, $sqlpass, $sqldb);
  
 // create a prepared statement 
 $stmt = mysqli_prepare($mysqli, "SELECT COUNT(*) FROM `usk_subs` WHERE `town` = ?;");

 // bind parameters for markers 
 mysqli_stmt_bind_param($stmt, "s", $user); 

 // execute query 
 mysqli_stmt_execute($stmt);
 
 mysqli_stmt_bind_result($stmt, $ret);
 mysqli_stmt_fetch($stmt);
  
 mysqli_stmt_close($stmt);
 mysqli_close($mysqli);   
 
 return($ret);
}
      
function list_followers($user)
{
 global $sqluser, $sqlpass, $sqldb;
   
 $mysqli = mysqli_connect('localhost', $sqluser, $sqlpass, $sqldb);
  
 // create a prepared statement 
 $stmt = mysqli_prepare($mysqli, "SELECT follower FROM `usk_subs` WHERE `town` = ?;");

 // bind parameters for markers 
 mysqli_stmt_bind_param($stmt, "s", $user); 

 // execute query 
 mysqli_stmt_execute($stmt);
 
 $ret_array = array();
 mysqli_stmt_bind_result($stmt, $f);
 while(mysqli_stmt_fetch($stmt))
 {
   $ret_array[] = "\"$f\"";
 }
  
 mysqli_stmt_close($stmt);
 mysqli_close($mysqli);   
 
 $ret = implode(",",$ret_array);
 return($ret);
}      
      
function output_followers($host,$user)
{
  $uuser = url_user($host,$user);
  $no    = count_followers($user);
  $fs    = list_followers($user);
  
  echo <<<END
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "$uuser/followers",
  "type": "OrderedCollection",
  "totalItems":$no,
  "orderedItems": [$fs]
}
END;
}
          
function output_following($host,$user)
{
  $uuser = url_user($host,$user);
  $fuser = url_user($host,"oslo");
  $guser = url_user($host,"bergen");
  echo <<<END
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "$uuser/following",
  "type": "OrderedCollection",
  "totalItems": 2,
  "orderedItems": ["$fuser/", "$guser/"]
}
END;

}


          
function accept_follower($host,$user,$inbox_id,$inbox_actor, $inbox)
{
  $inbox_host  = parse_url( $inbox_actor, PHP_URL_HOST );
  $uuser = url_user($host,$user);
  $guid  = rand();

  //  Create the Accept message
  $mess = <<<END
{
  "@context" : "https://www.w3.org/ns/activitystreams",
  "id"       : "https://{$host}/{$guid}",
  "type"     : "Accept",
  "actor"    : "$uuser/",
  "object"   : 
  {
    "@context" : "https://www.w3.org/ns/activitystreams",
    "id"       :  "$inbox_id",
    "type"     :  "Follow",
    "actor"    :  "$inbox_actor",
    "object"   :  "$uuser/"
  }
}
END;
 $message = $mess; //json_encode(json_decode($mess));
 log_text("Accept message",$message);
 
 $xhost = parse_url( $inbox, PHP_URL_HOST );
 $xpath = parse_url( $inbox, PHP_URL_PATH );

 //  Get signed headers
 $headers = generate_signed_headers( $host, $user, $message, $xhost, $xpath );
 
 //  Specify the URL of the remote server's inbox
 //  TODO: The path doesn't *always* end with /inbox
 $remoteServerUrl = $inbox;

 log_text("Remote server",$remoteServerUrl);
 
 //  POST the message and header to the requester's inbox
 $ch = curl_init( $remoteServerUrl );
 curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
 curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
 curl_setopt( $ch, CURLOPT_POSTFIELDS, $message );
 curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
 $response = curl_exec( $ch );
 $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 log_text("Accept response","$httpcode $response");
 //  Check for errors
 if( curl_errno( $ch ) ) 
 {
   log_text( "Accept error: ",  curl_error( $ch ) );
 }
 curl_close($ch);
 
 return ($httpcode > 200  && $httpcode < 300);
}

function output_embed($host,$user,$no)
{
  $uuser = url_user($host,$user);
  echo <<<END
{
  "type": "rich",
  "version": "1.0",
  "author_name": "NN",
  "author_url": "$uuser/",
  "provider_name": "usk.akerbaek.no",
  "provider_url": "$host",
  "cache_age": 86400,
  "html": "<code>Ingen innebygging. Lag lenke til <a href='https://underskog.no/kalender/$no'>https://underskog.no/kalender/$no</a> isteden.</code>",
  "width": 400,
  "height": null
}
END;

}

function output_mobilizon($host,$user,$id)
{
  echo <<<END
{"timezone":null,"isOnline":false,"contacts":[],"cc":["https://mobilizon.agdersam.no/@enannenen/followers"],
"id":"https://usk.akerbaek.no/user/$user/events/$id",
"inLanguage":"nb","endTime":"2026-05-09T19:00:00Z",
"repliesModerationOption":"allow_all",
"content":"<p>For å hedre Kalles liv og karriere arrangeres en offisiell minnekonsert</p>",
"category":"MUSIC",
"actor":"https://usk.akerbaek.no/user/enannenen/",
"type":"Event",
"url":"https://usk.akerbaek.no/events/$id",
"remainingAttendeeCapacity":null,
"anonymousParticipationEnabled":false,"ical:status":"CONFIRMED",
"to":["https://www.w3.org/ns/activitystreams#Public"],"joinMode":"free",
"location":{"address":{"addressCountry":"Noreg","addressLocality":"Halden","addressRegion":null,"postalCode":"1767","streetAddress":"Tollbugata","type":"PostalAddress"},
"id":"https://usk.akerbaek.no/address/937f420c-4dc2-434e-a6be-ec58c91c92f6","latitude":59.1190843,"longitude":11.3853614,"name":"Brygga Kultursal Halden","type":"Place"},"startTime":"2025-04-09T17:00:00Z","published":"2025-02-06T12:56:13Z","draft":false,"participantCount":1,"uuid":"f56a39d9-c418-4081-bff9-6295f91b6d83","maximumAttendeeCapacity":0,
"updated":"2025-03-12T16:40:05Z","attributedTo":"https://usk.akerbaek.no/user/enannenen/","commentsEnabled":true,
"name":"Living On Both Sides Now - Halden hyller Kalle","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"addressRegion":"sc:addressRegion",
"timezone":{"@id":"mz:timezone","@type":"sc:Text"},"isOnline":{"@id":"mz:isOnline","@type":"sc:Boolean"},"pt":"https://joinpeertube.org/ns#","manuallyApprovesFollowers":"as:manuallyApprovesFollowers","inLanguage":"sc:inLanguage","address":{"@id":"sc:address","@type":"sc:PostalAddress"},
"discoverable":"toot:discoverable","repliesModerationOption":{"@id":"mz:repliesModerationOption","@type":"mz:repliesModerationOptionType"},"sc":"http://schema.org#","mz":"https://joinmobilizon.org/ns#","category":"sc:category","joinModeType":{"@id":"mz:joinModeType","@type":"rdfs:Class"},"Hashtag":"as:Hashtag","propertyID":"sc:propertyID","PostalAddress":"sc:PostalAddress","discussions":{"@id":"mz:discussions","@type":"@id"},"remainingAttendeeCapacity":"sc:remainingAttendeeCapacity","streetAddress":"sc:streetAddress","anonymousParticipationEnabled":{"@id":"mz:anonymousParticipationEnabled","@type":"sc:Boolean"},"addressLocality":"sc:addressLocality","joinMode":{"@id":"mz:joinMode","@type":"mz:joinModeType"},"location":{"@id":"sc:location","@type":"sc:Place"},"toot":"http://joinmastodon.org/ns#","participantCount":{"@id":"mz:participantCount","@type":"sc:Integer"},"uuid":"sc:identifier","maximumAttendeeCapacity":"sc:maximumAttendeeCapacity","participationMessage":{"@id":"mz:participationMessage","@type":"sc:Text"},"openness":{"@id":"mz:openness","@type":"@id"},
"members":{"@id":"mz:members","@type":"@id"},"events":{"@id":"mz:events","@type":"@id"},"resources":{"@id":"mz:resources","@type":"@id"},"addressCountry":"sc:addressCountry","posts":{"@id":"mz:posts","@type":"@id"},"commentsEnabled":{"@id":"pt:commentsEnabled","@type":"sc:Boolean"},"value":"sc:value","PropertyValue":"sc:PropertyValue","repliesModerationOptionType":{"@id":"mz:repliesModerationOptionType","@type":"rdfs:Class"},"todos":{"@id":"mz:todos","@type":"@id"},"ical":"http://www.w3.org/2002/12/cal/ical#","postalCode":"sc:postalCode","memberCount":{"@id":"mz:memberCount","@type":"sc:Integer"},"@language":"und"}],"mediaType":"text/html"}
END;  
}
      
if(empty( $_GET["path"] )) http_response_code(400) && die("Hva vil du, tro?");

$path   = $_GET["path"];
$pattern = "/[\/]/";
$comp   = preg_split($pattern,$path);

$task   = $comp[1];
$user   = $comp[2];
$action = $comp[3];
if(isset($comp[4])) $id = $comp[4];

$sign= '';
if(isset($_SERVER['HTTP_SIGNATURE'])) $sign   = $_SERVER['HTTP_SIGNATURE'];
// $family = get_fedi_family($sign);

// echo "$task $user $action $id $family\n"; 
// die();

    switch ($task) 
    {
      case "profile":
//        $user = $_GET["user"];
        $byno = $byer[$user];
        if (!in_array($user, $cities))
          http_response_code(404) && die("Ukjent by");
        header( "Content-Type: text/html" );
        output_profile_html($host,$user,"https://underskog.no/kalender?city=$byno");
      break;
      case "user":
//        $user = $_GET["user"];
        if (in_array($user, $persons))
        {
          header( "Content-Type: application/activity+json; charset=utf-8" );
          output_person($host,$user);
          die();        
        }
        if (!in_array($user, $cities))
          http_response_code(404) && die("Ukjent by");
        switch($action)
        {
        case "embed":
//          $id = $_GET["id"];
          header( "Content-Type: application/json" );
          output_embed($host,$user,id2skog($id));
        break;
        case "outbox":
            log_data();
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'" );
            output_outbox($host,$user); 
        break;
        case "inbox":

          $body = json_decode( file_get_contents( "php://input" ), true );
          switch($body["type"])
          {
          case "Follow":
            log_data();
            $ok = false;
            $inbox_id    = $body["id"];
            $inbox_actor = $body["actor"];
            store_follower($user,$inbox_actor);
            $inbox       = get_inbox($inbox_actor,false);
            if($inbox) $ok = accept_follower($host,$user,$inbox_id,$inbox_actor,$inbox);
            if($ok)
            {
              verify_inbox($inbox_actor);
            }
            else
            {
              log_text("Accept following","failed, try again");
              $inbox = get_inbox($inbox_actor,true);  // Update inbox from source
              if($inbox) $ok = accept_follower($host,$user,$inbox_id,$inbox_actor,$inbox);
              if($ok) verify_inbox($inbox_actor);
            }
            
          break;
          case "Undo":
            log_data();
            // $inbox_id    = $body["id"];
            // $inbox_actor = $body["actor"];
            $undo_object = $body["object"];
            log_text("Undo type",$undo_object["type"]);
            log_text("Undo actor",$undo_object["actor"]);
            if($undo_object["type"] == "Follow")
            {
              forget_follower($user,$undo_object["actor"]);
              // Not neccesary to accept undo message  ?
            }
          break;
          case "Announce":
            log_data();
            $boost_object = $body["object"];
            log_text("Announce type",$boost_object["type"]);
            log_text("Announce actor",$boost_object["actor"]);
          break;
          default:
            log_text("Input Post Type",$body["type"],"logfile.x.txt");
            log_text("Actor", $body["actor"] );
            http_response_code(400) &&  die("Ukjent");
          }       
        break;
        case "followers":
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'" );
            output_followers($host,$user); 
        break;
        case "following":
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'" );
            output_following($host,$user); 
        break;
// TODO: members        
        case "members":
            header( "Content-Type: application/activity+json; charset=utf-8" );
            output_members($host,$user); 
        break;
        case "posts":
//          $id = $_GET["id"];
          log_data();
          log_text("Looking for post",$id);
          $ical = get_ics($user,false);
          $that = get_event_by_id($ical,id2skog($id));
          if(!$that)
            http_response_code(404) &&  die("Melding mangler");       
          log_text("Found",$that->summary);
          // Hvis http accept er html så redirect til ekstern side
          if(isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'],"json") !== false )
          {
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'" );

            $content = create_text_content($that,$user);
            $note = create_post($host,$user,$id,$content);
            //$message = create_create($host,$user,$user,$id,$note);  
            log_text("Message content",$note);
            echo $note;
            die();
          }
          else
          {
            $alt = get_main_url($that);
            log_text("Redirecting to",$alt);
//            header("Link: <https://$host/embed>; rel='alternate' type='application/json+oembed'");
//            header("Location: $alt", true, 303);
            header( "Content-Type: text/html" );
            output_profile_html($host,$user,$alt);
            die();
          }

        break;
        case "events":
          log_data();
          $family = get_fedi_family($sign);
          if($id == '')
          {
            log_text("All events",$id);
            header( "Content-Type: application/activity+json; charset=utf-8" );
            output_events($host,$user); 
            die();
          }
          if($id < 100)
           {
            log_text("Dummy event",$id);
            header( "Content-Type: application/activity+json; charset=utf-8" );
            output_mobilizon($host,$user,$id); 
            die();
          }
          
          log_text("Looking for event",$id);
          log_text("From fedi type",$family);
          $ical = get_ics($user,false);
          $that = get_event_by_id($ical,id2skog($id));
          if(!$that)
            http_response_code(404) &&  die("Evenement mangler");       
          log_text("Found",$that->summary);
          // Hvis http accept er html så redirect til ekstern side
          if(isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'],"json") !== false )
          {
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'; charset=utf-8" );

            if($family == 'mobilizon')
              $owner = 'enannenen';
            else
              $owner = $user;  
            $content = create_text_content($that,$user);
            $ret = create_event($host,$owner,$user,$id,$that,create_event_context());
            log_text("Message content",$ret);
            echo $ret;
            die();
          }
          else
          {
            $that = get_event_by_id_chron($ical,id2skog($id));
            $alt = get_main_url($that);
            log_text("Redirecting to",$alt);
//            header("Link: <https://$host/embed>; rel='alternate' type='application/json+oembed'");
//            header("Location: $alt", true, 307);
            header( "Content-Type: text/html" );
            output_page_html($host,$user,$that,$id);
            die();
          }
        break;
        default:
          if(isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'],"json") !== false )
          {
            header( "Content-Type: application/activity+json; charset=utf-8" );
//            header( "Content-Type: application/ld+json; profile='https://www.w3.org/ns/activitystreams'" );
            output_minimal($host,$user);
          }
          else
          {
            if (!in_array($user, $cities))
              http_response_code(404) && die("Ukjent by");
            $byno = $byer[$user];
            header( "Content-Type: text/html" );
            output_profile_html($host,$user,"https://underskog.no/kalender?city=$byno");
            die();
          }
        }  
      break;
      default:
        // var_dump($_SERVER);
    }
?>
