# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
"""
Create a new document with defaults set
"""

import frappe
from frappe.utils import nowdate, nowtime, now_datetime
import frappe.defaults
from frappe.model.db_schema import type_map
import copy

def get_new_doc(doctype, parent_doc = None, parentfield = None, as_dict=False):
	if doctype not in frappe.local.new_doc_templates:
		# cache a copy of new doc as it is called
		# frequently for inserts
		frappe.local.new_doc_templates[doctype] = make_new_doc(doctype)

	doc = copy.deepcopy(frappe.local.new_doc_templates[doctype])

	# doc = make_new_doc(doctype)

	set_dynamic_default_values(doc, parent_doc, parentfield)

	if as_dict:
		return doc
	else:
		return frappe.get_doc(doc)

def make_new_doc(doctype):
	doc = frappe.get_doc({
		"doctype": doctype,
		"__islocal": 1,
		"owner": frappe.session.user,
		"docstatus": 0
	})

	set_user_and_static_default_values(doc)

	doc._fix_numeric_types()
	doc = doc.get_valid_dict(sanitize=False)
	doc["doctype"] = doctype
	doc["__islocal"] = 1

	return doc

def set_user_and_static_default_values(doc):
	user_permissions = frappe.defaults.get_user_permissions()
	defaults = frappe.defaults.get_defaults()

	for df in doc.meta.get("fields"):
		if df.fieldtype in type_map:
			user_default_value = get_user_default_value(df, defaults, user_permissions)
			if user_default_value is not None:
				doc.set(df.fieldname, user_default_value)

			else:
				if df.fieldname != doc.meta.title_field:
					static_default_value = get_static_default_value(df, user_permissions)
					if static_default_value is not None:
						doc.set(df.fieldname, static_default_value)

def get_user_default_value(df, defaults, user_permissions):
	# don't set defaults for "User" link field using User Permissions!
	if df.fieldtype == "Link" and df.options != "User":
		# 1 - look in user permissions only for document_type==Setup
		# We don't want to include permissions of transactions to be used for defaults.
		if (frappe.get_meta(df.options).document_type=="Setup"
			and user_permissions_exist(df, user_permissions)
			and len(user_permissions[df.options])==1):
			return user_permissions[df.options][0]

		# 2 - Look in user defaults
		user_default = defaults.get(df.fieldname)
		is_allowed_user_default = user_default and (not user_permissions_exist(df, user_permissions)
			or (user_default in user_permissions.get(df.options, [])))

		# is this user default also allowed as per user permissions?
		if is_allowed_user_default:
			return user_default

def get_static_default_value(df, user_permissions):
	# 3 - look in default of docfield
	if df.get("default"):
		if df.default == "__user":
			return frappe.session.user

		elif df.default == "Today":
			return nowdate()

		elif not df.default.startswith(":"):
			# a simple default value
			is_allowed_default_value = (not user_permissions_exist(df, user_permissions)
				or (df.default in user_permissions.get(df.options, [])))

			if df.fieldtype!="Link" or df.options=="User" or is_allowed_default_value:
				return df.default

	elif (df.fieldtype == "Select" and df.options and df.options not in ("[Select]", "Loading...")):
		return df.options.split("\n")[0]

def set_dynamic_default_values(doc, parent_doc, parentfield):
	# these values should not be cached
	user_permissions = frappe.defaults.get_user_permissions()

	for df in frappe.get_meta(doc["doctype"]).get("fields"):
		if df.get("default"):
			if df.default.startswith(":"):
				default_value = get_default_based_on_another_field(df, user_permissions, parent_doc)
				if default_value is not None and not doc.get(df.fieldname):
					doc[df.fieldname] = default_value

			elif df.fieldtype == "Datetime" and df.default.lower() == "now":
				doc[df.fieldname] = now_datetime()

		if df.fieldtype == "Time":
			doc[df.fieldname] = nowtime()

	if parent_doc:
		doc["parent"] = parent_doc.name
		doc["parenttype"] = parent_doc.doctype

	if parentfield:
		doc["parentfield"] = parentfield

def user_permissions_exist(df, user_permissions):
	return (df.fieldtype=="Link"
		and not getattr(df, "ignore_user_permissions", False)
		and df.options in (user_permissions or []))

def get_default_based_on_another_field(df, user_permissions, parent_doc):
	# default value based on another document
	ref_doctype =  df.default[1:]
	ref_fieldname = ref_doctype.lower().replace(" ", "_")
	reference_name = parent_doc.get(ref_fieldname) if parent_doc else frappe.db.get_default(ref_fieldname)

	default_value = frappe.db.get_value(ref_doctype, reference_name, df.fieldname)
	is_allowed_default_value = (not user_permissions_exist(df, user_permissions) or
		(default_value in user_permissions.get(df.options, [])))

	# is this allowed as per user permissions
	if is_allowed_default_value:
		return default_value
