/* See COPYRIGHT for copyright information. */

#include <arch/arch.h>
#include <arch/mmu.h>
#include <bitmask.h>
#include <elf.h>
#include <smp.h>
#include <atomic.h>
#include <string.h>
#include <assert.h>
#include <process.h>
#include <pmap.h>
#include <trap.h>
#include <monitor.h>
#include <manager.h>
#include <stdio.h>
#include <schedule.h>
#include <kmalloc.h>
#include <mm.h>

#include <ros/syscall.h>
#include <error.h>

atomic_t num_envs;

// Initialize the kernel virtual memory layout for environment e.
// Allocate a page directory, set e->env_pgdir and e->env_cr3 accordingly,
// and initialize the kernel portion of the new environment's address space.
// Do NOT (yet) map anything into the user portion
// of the environment's virtual address space.
//
// Returns 0 on success, < 0 on error.  Errors include:
//	-ENOMEM if page directory or table could not be allocated.
//
int env_setup_vm(env_t *e)
{
	int i, ret;
	static page_t *shared_page = 0;

	if ((ret = arch_pgdir_setup(boot_pgdir, &e->env_pgdir)))
		return ret;
	e->env_cr3 = arch_pgdir_get_cr3(e->env_pgdir);

	/* These need to be contiguous, so the kernel can alias them.  Note the
	 * pages return with a refcnt, but it's okay to insert them since we
	 * free them manually when the process is cleaned up. */
	if (!(e->procinfo = kpages_alloc(PROCINFO_NUM_PAGES * PGSIZE,
					 MEM_WAIT)))
		goto env_setup_vm_error_i;
	if (!(e->procdata = kpages_alloc(PROCDATA_NUM_PAGES * PGSIZE,
					 MEM_WAIT)))
		goto env_setup_vm_error_d;
	/* Normally we would 0 the pages here.  We handle it in proc_init_proc*.
	 * Do not start the process without calling those. */
	for (int i = 0; i < PROCINFO_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir,
				kva2page((void*)e->procinfo + i * PGSIZE),
				(void*)(UINFO + i * PGSIZE), PTE_USER_RO) < 0)
			goto env_setup_vm_error;
	}
	for (int i = 0; i < PROCDATA_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir,
				kva2page((void*)e->procdata + i * PGSIZE),
				(void*)(UDATA + i * PGSIZE), PTE_USER_RW) < 0)
			goto env_setup_vm_error;
	}
	for (int i = 0; i < PROCGINFO_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir,
		                kva2page((void*)&__proc_global_info
					 + i * PGSIZE),
		                (void*)(UGINFO + i * PGSIZE), PTE_USER_RO) < 0)
			goto env_setup_vm_error;
	}
	/* Finally, set up the Global Shared Data page for all processes.  Can't
	 * be trusted, but still very useful at this stage for us.  Consider
	 * removing when we have real processes (TODO).
	 *
	 * Note the page is alloced only the first time through, and its ref is
	 * stored in shared_page. */
	if (!shared_page) {
		if (upage_alloc(e, &shared_page, 1) < 0)
			goto env_setup_vm_error;
	}
	if (page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_USER_RW)
	    < 0)
		goto env_setup_vm_error;

	return 0;

env_setup_vm_error:
	kpages_free(e->procdata, PROCDATA_NUM_PAGES * PGSIZE);
env_setup_vm_error_d:
	kpages_free(e->procinfo, PROCINFO_NUM_PAGES * PGSIZE);
env_setup_vm_error_i:
	env_user_mem_free(e, 0, UVPT);
	env_pagetable_free(e);
	return -ENOMEM;
}

/* Frees (decrefs) all memory mapped in the given range */
void env_user_mem_free(env_t* e, void* start, size_t len)
{
	assert((uintptr_t)start + len <= UVPT);
	int user_page_free(env_t* e, pte_t pte, void* va, void* arg)
	{
		if (!pte_is_mapped(pte))
			return 0;
		page_t *page = pa2page(pte_get_paddr(pte));
		pte_clear(pte);
		page_decref(page);
		/* TODO: consider other states here (like !P, yet still tracking
		 * a page, for VM tricks, page map stuff, etc.  Should be okay:
		 * once we're freeing, everything else about this proc is dead.
		 * */
		return 0;
	}

	env_user_mem_walk(e,start,len,&user_page_free,NULL);
	tlbflush();
}

void set_username(struct username *u, char *name)
{
	ERRSTACK(1);

	spin_lock(&u->name_lock);

	if (waserror()) {
		spin_unlock(&u->name_lock);
		nexterror();
	}

	__set_username(u, name);

	poperror();
	spin_unlock(&u->name_lock);
}

/*
 * This function exists so that you can do your own locking - do not use it
 * without locking the username's spinlock yourself.
 */
void __set_username(struct username *u, char *name)
{
	if (!name)
		error(EINVAL, "New username is NULL");

	if (strlen(name) > sizeof(u->name) - 1)
		error(EINVAL,
		      "New username for process more than %d chars long",
		      sizeof(u->name) - 1);

	// 'backward' copy since reads aren't protected
	u->name[0] = 0;
	wmb(); // ensure user.name="" before writing the rest of the new name
	strlcpy(&u->name[1], &name[1], sizeof(u->name));
	wmb(); // ensure new name is written before writing first byte
	u->name[0] = name[0];
}
